[Debian-ha-commits] [fence-agents] 03/04: Imported Upstream version 4.0.17

Richard Winters devrik-guest at moszumanska.debian.org
Thu Apr 16 08:06:54 UTC 2015


This is an automated email from the git hooks/post-receive script.

devrik-guest pushed a commit to branch master
in repository fence-agents.

commit 4a97a31b1d63615cbfbc06b7b611e344bb469a18
Author: Richard B Winters <rik at mmogp.com>
Date:   Thu Apr 16 03:54:27 2015 -0400

    Imported Upstream version 4.0.17
---
 .gitignore                                      |    3 +
 Makefile.am                                     |    4 +-
 README.md                                       |    9 +
 autogen.sh                                      |    2 +-
 configure.ac                                    |   46 +-
 fence/agents/Makefile.am                        |    3 +-
 fence/agents/alom/Makefile.am                   |    6 +-
 fence/agents/alom/fence_alom.py                 |   30 +-
 fence/agents/amt/Makefile.am                    |    6 +-
 fence/agents/amt/fence_amt.py                   |  199 ++--
 fence/agents/apc/Makefile.am                    |    6 +-
 fence/agents/apc/fence_apc.py                   |  125 +-
 fence/agents/apc_snmp/Makefile.am               |   13 +-
 fence/agents/apc_snmp/fence_apc_snmp.py         |  116 +-
 fence/agents/baytech/Makefile.am                |   17 -
 fence/agents/baytech/fence_baytech.pl           |  746 ------------
 fence/agents/bladecenter/Makefile.am            |    6 +-
 fence/agents/bladecenter/fence_bladecenter.py   |   55 +-
 fence/agents/brocade/Makefile.am                |    6 +-
 fence/agents/brocade/fence_brocade.py           |   72 +-
 fence/agents/bullpap/Makefile.am                |   17 -
 fence/agents/bullpap/fence_bullpap.pl           |  433 -------
 fence/agents/cisco_mds/Makefile.am              |    6 +-
 fence/agents/cisco_mds/fence_cisco_mds.py       |   35 +-
 fence/agents/cisco_ucs/Makefile.am              |    6 +-
 fence/agents/cisco_ucs/fence_cisco_ucs.py       |  138 ++-
 fence/agents/cpint/Makefile.am                  |   17 -
 fence/agents/cpint/fence_cpint.pl               |  188 ---
 fence/agents/{apc => docker}/Makefile.am        |    8 +-
 fence/agents/docker/fence_docker.py             |  152 +++
 fence/agents/drac/Makefile.am                   |    6 +-
 fence/agents/drac/fence_drac.py                 |   38 +-
 fence/agents/drac5/Makefile.am                  |    6 +-
 fence/agents/drac5/fence_drac5.py               |   69 +-
 fence/agents/dummy/Makefile.am                  |    4 +-
 fence/agents/dummy/fence_dummy.py               |   43 +-
 fence/agents/eaton_snmp/Makefile.am             |    6 +-
 fence/agents/eaton_snmp/fence_eaton_snmp.py     |   78 +-
 fence/agents/egenera/Makefile.am                |   17 -
 fence/agents/egenera/fence_egenera.pl           |  501 --------
 fence/agents/{apc => emerson}/Makefile.am       |    8 +-
 fence/agents/emerson/fence_emerson.py           |   68 ++
 fence/agents/eps/Makefile.am                    |    6 +-
 fence/agents/eps/fence_eps.py                   |   52 +-
 fence/agents/hds_cb/Makefile.am                 |    6 +-
 fence/agents/hds_cb/fence_hds_cb.py             |   74 +-
 fence/agents/hpblade/Makefile.am                |    6 +-
 fence/agents/hpblade/fence_hpblade.py           |   42 +-
 fence/agents/ibmblade/Makefile.am               |    6 +-
 fence/agents/ibmblade/fence_ibmblade.py         |   21 +-
 fence/agents/ifmib/Makefile.am                  |    6 +-
 fence/agents/ifmib/fence_ifmib.py               |   40 +-
 fence/agents/ilo/Makefile.am                    |    7 +-
 fence/agents/ilo/fence_ilo.py                   |   32 +-
 fence/agents/{apc => ilo_moonshot}/Makefile.am  |    8 +-
 fence/agents/ilo_moonshot/fence_ilo_moonshot.py |   69 ++
 fence/agents/ilo_mp/Makefile.am                 |    6 +-
 fence/agents/ilo_mp/fence_ilo_mp.py             |   32 +-
 fence/agents/{ipmilan => ilo_ssh}/Makefile.am   |   12 +-
 fence/agents/ilo_ssh/fence_ilo_ssh.py           |   75 ++
 fence/agents/intelmodular/Makefile.am           |    6 +-
 fence/agents/intelmodular/fence_intelmodular.py |   24 +-
 fence/agents/ipdu/Makefile.am                   |    6 +-
 fence/agents/ipdu/fence_ipdu.py                 |   44 +-
 fence/agents/ipmilan/Makefile.am                |    6 +-
 fence/agents/ipmilan/fence_ipmilan.py           |  276 ++---
 fence/agents/kdump/Makefile.am                  |    6 +
 fence/agents/kdump/fence_kdump.c                |   35 +-
 fence/agents/kdump/options.h                    |    2 +
 fence/agents/ldom/Makefile.am                   |    6 +-
 fence/agents/ldom/fence_ldom.py                 |   72 +-
 fence/agents/lib/Makefile.am                    |    5 +-
 fence/agents/lib/XenAPI.py.py                   |    8 +-
 fence/agents/lib/check_used_options.py          |   22 +-
 fence/agents/lib/fence2rng.xsl                  |   25 +-
 fence/agents/lib/fence2wiki.xsl                 |   14 +
 fence/agents/lib/fencing.py.py                  | 1407 ++++++++++++++---------
 fence/agents/lib/fencing_snmp.py.py             |   75 +-
 fence/agents/lib/tests/test_fencing.py          |  123 ++
 fence/agents/lib/transfer.py                    |   16 -
 fence/agents/lpar/Makefile.am                   |    6 +-
 fence/agents/lpar/fence_lpar.py                 |   79 +-
 fence/agents/mcdata/Makefile.am                 |   17 -
 fence/agents/mcdata/fence_mcdata.pl             |  361 ------
 fence/agents/{apc => mpath}/Makefile.am         |    8 +-
 fence/agents/mpath/fence_mpath.py               |  247 ++++
 fence/agents/netio/Makefile.am                  |    6 +-
 fence/agents/netio/fence_netio.py               |   61 +-
 fence/agents/ovh/Makefile.am                    |    6 +-
 fence/agents/ovh/fence_ovh.py                   |  107 +-
 fence/agents/{apc => pve}/Makefile.am           |    8 +-
 fence/agents/pve/fence_pve.py                   |  183 +++
 fence/agents/rackswitch/Makefile.am             |   16 -
 fence/agents/rackswitch/do_rack.c               |  807 -------------
 fence/agents/rackswitch/do_rack.h               |   27 -
 fence/agents/{apc => raritan}/Makefile.am       |    8 +-
 fence/agents/raritan/fence_raritan.py           |   90 ++
 fence/agents/rhevm/Makefile.am                  |    6 +-
 fence/agents/rhevm/fence_rhevm.py               |  108 +-
 fence/agents/rsa/Makefile.am                    |    6 +-
 fence/agents/rsa/fence_rsa.py                   |   32 +-
 fence/agents/rsb/Makefile.am                    |    6 +-
 fence/agents/rsb/fence_rsb.py                   |   52 +-
 fence/agents/sanbox2/Makefile.am                |    6 +-
 fence/agents/sanbox2/fence_sanbox2.py           |   49 +-
 fence/agents/scsi/Makefile.am                   |   21 +-
 fence/agents/scsi/fence_scsi.8                  |  119 --
 fence/agents/scsi/fence_scsi.pl                 |  875 --------------
 fence/agents/scsi/fence_scsi.py                 |  454 ++++++++
 fence/agents/scsi/fence_scsi_check.pl           |  170 ---
 fence/agents/virsh/Makefile.am                  |    6 +-
 fence/agents/virsh/fence_virsh.py               |   51 +-
 fence/agents/vixel/Makefile.am                  |   17 -
 fence/agents/vixel/fence_vixel.pl               |  267 -----
 fence/agents/vmware/Makefile.am                 |    5 +-
 fence/agents/vmware/fence_vmware.py             |  149 +--
 fence/agents/vmware_soap/Makefile.am            |    6 +-
 fence/agents/vmware_soap/fence_vmware_soap.py   |  127 +-
 fence/agents/wti/Makefile.am                    |    6 +-
 fence/agents/wti/fence_wti.py                   |  130 ++-
 fence/agents/xcat/Makefile.am                   |   17 -
 fence/agents/xcat/fence_xcat.pl                 |  250 ----
 fence/agents/xenapi/Makefile.am                 |    6 +-
 fence/agents/xenapi/fence_xenapi.py             |   53 +-
 fence/agents/zvm/Makefile.am                    |   18 +-
 fence/agents/zvm/fence_zvm.8                    |   81 --
 fence/agents/zvm/fence_zvm.c                    |  394 ++++++-
 fence/agents/zvm/fence_zvm.h                    |    3 +
 fence/agents/zvm/fence_zvmip.8                  |   86 --
 fence/agents/zvm/fence_zvmip.c                  |  388 ++++++-
 fence/agents/zvm/fence_zvmip.py                 |  175 +++
 make/ac_python_module.m4                        |   30 +
 make/agentccheck.mk                             |   22 +
 make/agentpycheck.mk                            |   31 +
 make/fencebuild.mk                              |   19 +-
 make/fenceman.mk                                |    5 +-
 make/fencemanc.mk                               |    3 +-
 make/fencemanperl.mk                            |    3 +-
 tests/data/metadata/fence_alom.xml              |  131 +++
 tests/data/metadata/fence_amt.xml               |  135 +++
 tests/data/metadata/fence_apc.xml               |  153 +++
 tests/data/metadata/fence_apc_snmp.xml          |  182 +++
 tests/data/metadata/fence_bladecenter.xml       |  153 +++
 tests/data/metadata/fence_brocade.xml           |  147 +++
 tests/data/metadata/fence_cisco_mds.xml         |  181 +++
 tests/data/metadata/fence_cisco_ucs.xml         |  148 +++
 tests/data/metadata/fence_docker.xml            |  146 +++
 tests/data/metadata/fence_drac.xml              |  116 ++
 tests/data/metadata/fence_drac5.xml             |  157 +++
 tests/data/metadata/fence_dummy.xml             |   93 ++
 tests/data/metadata/fence_eaton_snmp.xml        |  182 +++
 tests/data/metadata/fence_emerson.xml           |  182 +++
 tests/data/metadata/fence_eps.xml               |  125 ++
 tests/data/metadata/fence_hds_cb.xml            |  153 +++
 tests/data/metadata/fence_hpblade.xml           |  153 +++
 tests/data/metadata/fence_ibmblade.xml          |  182 +++
 tests/data/metadata/fence_idrac.xml             |  162 +++
 tests/data/metadata/fence_ifmib.xml             |  183 +++
 tests/data/metadata/fence_ilo.xml               |  142 +++
 tests/data/metadata/fence_ilo2.xml              |  142 +++
 tests/data/metadata/fence_ilo3.xml              |  162 +++
 tests/data/metadata/fence_ilo3_ssh.xml          |  146 +++
 tests/data/metadata/fence_ilo4.xml              |  162 +++
 tests/data/metadata/fence_ilo4_ssh.xml          |  146 +++
 tests/data/metadata/fence_ilo_moonshot.xml      |  143 +++
 tests/data/metadata/fence_ilo_mp.xml            |  136 +++
 tests/data/metadata/fence_ilo_ssh.xml           |  146 +++
 tests/data/metadata/fence_imm.xml               |  162 +++
 tests/data/metadata/fence_intelmodular.xml      |  184 +++
 tests/data/metadata/fence_ipdu.xml              |  182 +++
 tests/data/metadata/fence_ipmilan.xml           |  162 +++
 tests/data/metadata/fence_kdump.xml             |   52 +
 tests/data/metadata/fence_ldom.xml              |  145 +++
 tests/data/metadata/fence_lpar.xml              |  156 +++
 tests/data/metadata/fence_mpath.xml             |  100 ++
 tests/data/metadata/fence_netio.xml             |  123 ++
 tests/data/metadata/fence_ovh.xml               |  102 ++
 tests/data/metadata/fence_pve.xml               |  123 ++
 tests/data/metadata/fence_raritan.xml           |  123 ++
 tests/data/metadata/fence_rhevm.xml             |  148 +++
 tests/data/metadata/fence_rsa.xml               |  136 +++
 tests/data/metadata/fence_rsb.xml               |  136 +++
 tests/data/metadata/fence_sanbox2.xml           |  127 ++
 tests/data/metadata/fence_scsi.xml              |  116 ++
 tests/data/metadata/fence_tripplite_snmp.xml    |  182 +++
 tests/data/metadata/fence_virsh.xml             |  155 +++
 tests/data/metadata/fence_vmware_soap.xml       |  145 +++
 tests/data/metadata/fence_wti.xml               |  148 +++
 tests/data/metadata/fence_xenapi.xml            |  103 ++
 tests/data/metadata/fence_zvmip.xml             |  140 +++
 190 files changed, 12556 insertions(+), 7264 deletions(-)

diff --git a/.gitignore b/.gitignore
index a711b3a..8bcae2b 100644
--- a/.gitignore
+++ b/.gitignore
@@ -39,6 +39,7 @@ fence/agents/bullpap/fence_bullpap
 fence/agents/cisco_mds/fence_cisco_mds
 fence/agents/cisco_ucs/fence_cisco_ucs
 fence/agents/cpint/fence_cpint
+fence/agents/docker/fence_docker
 fence/agents/drac/fence_drac
 fence/agents/drac5/fence_drac5
 fence/agents/eaton_snmp/fence_eaton_snmp
@@ -65,8 +66,10 @@ 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
 fence/agents/rsa/fence_rsa
 fence/agents/rsb/fence_rsb
 fence/agents/sanbox2/fence_sanbox2
diff --git a/Makefile.am b/Makefile.am
index 1bd077a..5e2e22d 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -1,6 +1,6 @@
 EXTRA_DIST		= autogen.sh make/fencebuild.mk scripts/fenceparse \
 			  .version make/release.mk \
-			  make/git-version-gen make/gitlog-to-changelog
+			  make/git-version-gen make/gitlog-to-changelog tests
 
 AUTOMAKE_OPTIONS	= foreign
 
@@ -15,7 +15,7 @@ noinst_HEADERS		= make/copyright.cf
 
 ACLOCAL_AMFLAGS		= -I m4
 
-SUBDIRS			= fence doc
+SUBDIRS			= fence/agents/lib fence doc
 
 install-exec-local:
 			$(INSTALL) -d $(DESTDIR)/$(LOGDIR)
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..f0bbe43
--- /dev/null
+++ b/README.md
@@ -0,0 +1,9 @@
+# fence-agents
+Fence agents
+ Fence agents were developed as "drivers" for devices that are able to prevent computers of destroying data on shared storage. Their target is to isolate corrupted computer, there are three main ways:
+
+  * electric power - computer that is switched off can not corrupt data but it is important to not perform so called "soft- reboot" where applications are closed correctly as we do not know if this is possible. Similarly it works also for virtual machines when fence device is a hypervisor.
+  * network - network switches can forbid routing from selected computer, so even if computer is running it is not able to work with data
+  * data - Fibre-channel switches or SCSI devices allows us to limit who can write to managed disks 
+
+Fence agents do not use configuration files as configuration management is outside their scope. All of the arguments have to be specified either as command-line arguments or lines on standard input (take a look at complete list). Because fence agents are quite similar, fencing library (in Python) was developed and we will assume that you will use it for further developing. Creating or modifying a new fence agent should be quite simple. 
diff --git a/autogen.sh b/autogen.sh
index 3c5e1d9..ee22af8 100755
--- a/autogen.sh
+++ b/autogen.sh
@@ -1,4 +1,4 @@
 #!/bin/sh
 # Run this to generate all the initial makefiles, etc.
 mkdir -p m4
-autoreconf -i -v && echo Now run ./configure and make
+autoreconf -i -I make -v && echo Now run ./configure and make
diff --git a/configure.ac b/configure.ac
index eaef1d8..ce2ca46 100644
--- a/configure.ac
+++ b/configure.ac
@@ -12,7 +12,7 @@ LT_PREREQ([2.2.6])
 LT_INIT
 
 AC_CONFIG_MACRO_DIR([m4])
-AC_CONFIG_SRCDIR([fence/agents/rackswitch/do_rack.h])
+AC_CONFIG_SRCDIR([fence/agents/lib/fencing.py.py])
 AC_CONFIG_HEADERS([make/clusterautoconfig.h])
 
 AC_CANONICAL_HOST
@@ -108,12 +108,6 @@ AC_ARG_WITH([fenceagentslibdir],
 	[ FENCEAGENTSLIBDIR="$withval" ],
 	[ FENCEAGENTSLIBDIR="${datadir}/fence" ])
 
-AC_ARG_WITH([snmpbin],
-	[  --with-snmpbin=PATH
-                          path to snmp binaries (snmpwalk/get). ],
-	[ SNMPBIN="$withval" ],
-	[ SNMPBIN="${bindir}" ])
-
 AC_ARG_WITH([default-config-dir],
 	[  --with-default-config-dir=DIR
 			  cluster config directory. ],
@@ -159,10 +153,28 @@ LOGDIR=${localstatedir}/log/cluster
 CLUSTERVARRUN=${localstatedir}/run/cluster
 CLUSTERDATA=${datadir}/cluster
 
+AC_PYTHON_MODULE(suds, 1)
+AC_PYTHON_MODULE(pexpect, 1)
+AC_PYTHON_MODULE(pycurl, 1)
+AC_PYTHON_MODULE(requests, 1)
+
 ## path to 3rd-party binaries
 AC_PATH_PROG([IPMITOOL_PATH], [ipmitool], [/usr/bin/ipmitool])
 AC_PATH_PROG([AMTTOOL_PATH], [amttool], [/usr/bin/amttool])
 AC_PATH_PROG([GNUTLSCLI_PATH], [gnutlscli], [/usr/bin/gnutls-cli])
+AC_PATH_PROG([COROSYNC_CMAPCTL_PATH], [corosync-cmapctl], [/usr/sbin/corosync-cmapctl])
+AC_PATH_PROG([SG_PERSIST_PATH], [sg_persist], [/usr/bin/sg_persist])
+AC_PATH_PROG([SG_TURS_PATH], [sg_turs], [/usr/bin/sg_turs])
+AC_PATH_PROG([VGS_PATH], [vgs], [/usr/sbin/vgs])
+AC_PATH_PROG([SUDO_PATH], [sudo], [/usr/bin/sudo])
+AC_PATH_PROG([SSH_PATH], [ssh], [/usr/bin/ssh])
+AC_PATH_PROG([TELNET_PATH], [telnet], [/usr/bin/telnet])
+AC_PATH_PROG([MPATH_PATH], [mpathpersist], [/usr/sbin/mpathpersist])
+AC_PATH_PROG([SUDO_PATH], [sudo], [/usr/bin/sudo])
+AC_PATH_PROG([SNMPWALK_PATH], [snmpwalk], [/usr/bin/snmpwalk])
+AC_PATH_PROG([SNMPSET_PATH], [snmpset], [/usr/bin/snmpset])
+AC_PATH_PROG([SNMPGET_PATH], [snmpget], [/usr/bin/snmpget])
+
 ## do subst
 
 AC_SUBST([DEFAULT_CONFIG_DIR])
@@ -189,6 +201,10 @@ AM_CONDITIONAL(BUILD_XENAPILIB, test $XENAPILIB -eq 1)
 
 AC_SUBST([IPMITOOL_PATH])
 AC_SUBST([AMTTOOL_PATH])
+AC_SUBST([COROSYNC_CMAPCTL_PATH])
+AC_SUBST([SG_PERSIST_PATH])
+AC_SUBST([SG_TURS_PATH])
+AC_SUBST([VGS_PATH])
 
 ## *FLAGS handling
 
@@ -246,6 +262,7 @@ CFLAGS="$ENV_CFLAGS $OPT_CFLAGS $GDB_FLAGS \
 CPPFLAGS="-I\$(top_builddir)/make -I\$(top_srcdir)/make -I. $ENV_CPPFLAGS"
 LDFLAGS="$ENV_LDFLAGS"
 
+
 AC_CONFIG_FILES([Makefile
 		 fence/Makefile
 		 fence/agents/Makefile
@@ -253,25 +270,25 @@ AC_CONFIG_FILES([Makefile
 		 fence/agents/apc/Makefile
 		 fence/agents/apc_snmp/Makefile
 		 fence/agents/amt/Makefile 
-		 fence/agents/baytech/Makefile
 		 fence/agents/bladecenter/Makefile
 		 fence/agents/brocade/Makefile
-		 fence/agents/bullpap/Makefile
 		 fence/agents/cisco_mds/Makefile
 		 fence/agents/cisco_ucs/Makefile
-		 fence/agents/cpint/Makefile
+		 fence/agents/docker/Makefile
 		 fence/agents/drac/Makefile
 		 fence/agents/drac5/Makefile
 		 fence/agents/dummy/Makefile
 		 fence/agents/eaton_snmp/Makefile
-		 fence/agents/egenera/Makefile
+		 fence/agents/emerson/Makefile
 		 fence/agents/eps/Makefile
 		 fence/agents/hpblade/Makefile
 		 fence/agents/ibmblade/Makefile
 		 fence/agents/ipdu/Makefile
 		 fence/agents/ifmib/Makefile
 		 fence/agents/ilo/Makefile
+		 fence/agents/ilo_moonshot/Makefile
 		 fence/agents/ilo_mp/Makefile
+		 fence/agents/ilo_ssh/Makefile
 		 fence/agents/intelmodular/Makefile
 		 fence/agents/ipmilan/Makefile
 		 fence/agents/kdump/Makefile
@@ -279,21 +296,20 @@ AC_CONFIG_FILES([Makefile
 		 fence/agents/lib/Makefile
 		 fence/agents/lpar/Makefile
 		 fence/agents/manual/Makefile
-		 fence/agents/mcdata/Makefile
+		 fence/agents/mpath/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
 		 fence/agents/rsb/Makefile
 		 fence/agents/sanbox2/Makefile
 		 fence/agents/scsi/Makefile
 		 fence/agents/virsh/Makefile
-		 fence/agents/vixel/Makefile
 		 fence/agents/vmware/Makefile
 		 fence/agents/vmware_soap/Makefile
 		 fence/agents/wti/Makefile
-		 fence/agents/xcat/Makefile
 		 fence/agents/xenapi/Makefile
 		 fence/agents/hds_cb/Makefile
 		 fence/agents/zvm/Makefile
diff --git a/fence/agents/Makefile.am b/fence/agents/Makefile.am
index c47f5d5..3b76b9a 100644
--- a/fence/agents/Makefile.am
+++ b/fence/agents/Makefile.am
@@ -1,4 +1,3 @@
 MAINTAINERCLEANFILES	= Makefile.in
 
-SUBDIRS 		= lib \
-			  $(AGENTS_LIST)
+SUBDIRS 		= $(AGENTS_LIST)
diff --git a/fence/agents/alom/Makefile.am b/fence/agents/alom/Makefile.am
index 972f8a9..1051726 100644
--- a/fence/agents/alom/Makefile.am
+++ b/fence/agents/alom/Makefile.am
@@ -10,8 +10,8 @@ sbin_SCRIPTS		= $(TARGET)
 
 man_MANS		= $(TARGET).8
 
+FENCE_TEST_ARGS         = -l test -p test -a test
+
 include $(top_srcdir)/make/fencebuild.mk
 include $(top_srcdir)/make/fenceman.mk
-
-clean-local: clean-man
-	rm -f $(TARGET)
+include $(top_srcdir)/make/agentpycheck.mk
diff --git a/fence/agents/alom/fence_alom.py b/fence/agents/alom/fence_alom.py
index ef2db3c..1e95ac4 100644
--- a/fence/agents/alom/fence_alom.py
+++ b/fence/agents/alom/fence_alom.py
@@ -1,11 +1,12 @@
-#!/usr/bin/python
+#!/usr/bin/python -tt
 
 # The Following Agent Has Been Tested On:
 #
 # Sun(tm) Advanced Lights Out Manager CMT v1.6.1
 # as found on SUN T2000 Niagara
 
-import sys, re, pexpect, time, exceptions
+import sys, re, time
+import atexit
 sys.path.append("@FENCEAGENTSLIBDIR@")
 from fencing import *
 
@@ -17,7 +18,7 @@ BUILD_DATE=""
 
 def get_power_status(conn, options):
 	conn.send_eol("showplatform")
-	conn.log_expect(options, options["--command-prompt"], int(options["--shell-timeout"]))
+	conn.log_expect(options["--command-prompt"], int(options["--shell-timeout"]))
 	status = re.search("standby", conn.before.lower())
 	result = (status != None and "off" or "on")
 
@@ -26,39 +27,32 @@ def get_power_status(conn, options):
 def set_power_status(conn, options):
 	cmd_line = (options["--action"] == "on" and "poweron" or "poweroff -f -y")
 	conn.send_eol(cmd_line)
-	conn.log_expect(options, options["--command-prompt"], int(options["--power-timeout"]))
+	conn.log_expect(options["--command-prompt"], int(options["--power-timeout"]))
 	# Get the machine some time between poweron and poweroff
 	time.sleep(int(options["--power-timeout"]))
-		
+
 def main():
-	device_opt = [ "ipaddr", "login", "passwd", "cmd_prompt", "secure" ]
+	device_opt = ["ipaddr", "login", "passwd", "cmd_prompt", "secure"]
 
 	atexit.register(atexit_handler)
 
 	all_opt["secure"]["default"] = "1"
-	all_opt["cmd_prompt"]["default"] = [ "sc\>\ " ]
+	all_opt["cmd_prompt"]["default"] = [r"sc\>\ "]
 
 	options = check_input(device_opt, process_input(device_opt))
 	options["telnet_over_ssh"] = 1
-	
-	docs = { }
+
+	docs = {}
 	docs["shortdesc"] = "Fence agent for Sun ALOM"
 	docs["longdesc"] = "fence_alom is an I/O Fencing \
 agent which can be used with ALOM connected machines."
 	docs["vendorurl"] = "http://www.sun.com"
 	show_docs(options, docs)
-		
+
 	# Operate the fencing device
 	conn = fence_login(options)
 	result = fence_action(conn, options, set_power_status, get_power_status, None)
-
-	# Logout from system
-	try:
-		conn.send_eol("logout")
-		conn.close()
-	except:
-		pass	                                         
-
+	fence_logout(conn, "logout")
 	sys.exit(result)
 
 if __name__ == "__main__":
diff --git a/fence/agents/amt/Makefile.am b/fence/agents/amt/Makefile.am
index 9902731..5237f87 100644
--- a/fence/agents/amt/Makefile.am
+++ b/fence/agents/amt/Makefile.am
@@ -10,8 +10,8 @@ sbin_SCRIPTS		= $(TARGET)
 
 man_MANS		= $(TARGET).8
 
+FENCE_TEST_ARGS         = -p test -a test
+
 include $(top_srcdir)/make/fencebuild.mk
 include $(top_srcdir)/make/fenceman.mk
-
-clean-local: clean-man
-	rm -f $(TARGET)
+include $(top_srcdir)/make/agentpycheck.mk
diff --git a/fence/agents/amt/fence_amt.py b/fence/agents/amt/fence_amt.py
index 81b8aec..98ec554 100644
--- a/fence/agents/amt/fence_amt.py
+++ b/fence/agents/amt/fence_amt.py
@@ -1,9 +1,11 @@
-#!/usr/bin/python
+#!/usr/bin/python -tt
 
-import sys, subprocess, re, os, stat
+import sys, re, os
+import atexit
 from pipes import quote
 sys.path.append("@FENCEAGENTSLIBDIR@")
 from fencing import *
+from fencing import fail_usage, is_executable, run_command, run_delay
 
 #BEGIN_VERSION_GENERATION
 RELEASE_VERSION="Fence agent for Intel AMT"
@@ -12,140 +14,111 @@ BUILD_DATE=""
 #END_VERSION_GENERATION
 
 def get_power_status(_, options):
+	output = amt_run_command(options, create_command(options, "status"))
+	match = re.search('Powerstate:[\\s]*(..)', str(output))
+	status = match.group(1) if match else None
 
-    cmd = create_command(options, "status")
-
-    if options["log"] >= LOG_MODE_VERBOSE:
-        options["debug_fh"].write("executing: " + cmd + "\n")
-
-    try:
-        process = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
-    except OSError:
-        fail_usage("Amttool not found or not accessible")
-
-    process.wait()
-
-    output = process.communicate()
-    process.stdout.close()
-    options["debug_fh"].write(output)
-
-    match = re.search('Powerstate:[\\s]*(..)', str(output))
-    status = match.group(1) if match else None
-
-    if (status == None):
-        return "fail"
-    elif (status == "S0"): # SO = on; S3 = sleep; S5 = off
-        return "on"
-    else:
-        return "off"
+	if status == None:
+		return "fail"
+	elif status == "S0": # SO = on; S3 = sleep; S5 = off
+		return "on"
+	else:
+		return "off"
 
 def set_power_status(_, options):
-
-    cmd = create_command(options, options["--action"])
-
-    if options["log"] >= LOG_MODE_VERBOSE:
-        options["debug_fh"].write("executing: " + cmd + "\n")
-
-    try:
-        process = subprocess.Popen(cmd, stdout=options["debug_fh"], stderr=options["debug_fh"], shell=True)
-    except OSError:
-        fail_usage("Amttool not found or not accessible")
-
-    process.wait()
-
-    return
+	amt_run_command(options, create_command(options, options["--action"]))
+	return
 
 def reboot_cycle(_, options):
-    cmd = create_command(options, "cycle")
+	(status, _, _) = run_command(options, create_command(options, "cycle"))
+	return not bool(status)
 
-    if options["log"] >= LOG_MODE_VERBOSE:
-        options["debug_fh"].write("executing: " + cmd + "\n")
+def amt_run_command(options, command, timeout=None):
+	env = os.environ.copy()
 
-    try:
-        process = subprocess.Popen(cmd, stdout=options["debug_fh"], stderr=options["debug_fh"], shell=True)
-    except OSError:
-        fail_usage("Amttool not found or not accessible")
+	x = quote(options["--password"])
+	x = x[:-1] if x.endswith("'") else x
+	x = x[1:] if x.startswith("'") else x
+	env["AMT_PASSWORD"] = x
 
-    status = process.wait()
-    
-    return not bool(status)
+	return run_command(options, command, timeout, env)
 
 def create_command(options, action):
-
-    # --password / -p
-    cmd = "AMT_PASSWORD=" + quote(options["--password"])
-
-    cmd += " " + options["--amttool-path"]
-
-    # --ip / -a
-    cmd += " " + options["--ip"]
-
-    # --action / -o
-    if action == "status":
-        cmd += " info"
-    elif action == "on":
-        cmd = "echo \"y\"|" + cmd
-        cmd += " powerup"
-    elif action == "off":
-        cmd = "echo \"y\"|" + cmd
-        cmd += " powerdown"
-    elif action == "cycle":
-        cmd = "echo \"y\"|" + cmd
-        cmd += " powercycle"
-    if action in ["on", "off", "cycle"] and options.has_key("--boot-option"):
-        cmd += options["--boot-option"]
-
-    # --use-sudo / -d
-    if options.has_key("--use-sudo"):
-        cmd = SUDO_PATH + " " + cmd
-
-    return cmd
+	cmd = options["--amttool-path"]
+
+	# --ip / -a
+	cmd += " " + options["--ip"]
+
+	# --action / -o
+	if action == "status":
+		cmd += " info"
+	elif action == "on":
+		cmd = "echo \"y\"|" + cmd
+		cmd += " powerup"
+	elif action == "off":
+		cmd = "echo \"y\"|" + cmd
+		cmd += " powerdown"
+	elif action == "cycle":
+		cmd = "echo \"y\"|" + cmd
+		cmd += " powercycle"
+	if action in ["on", "off", "cycle"] and options.has_key("--boot-option"):
+		cmd += options["--boot-option"]
+
+	# --use-sudo / -d
+	if options.has_key("--use-sudo"):
+		cmd = options["--sudo-path"] + " " + cmd
+
+	return cmd
 
 def define_new_opts():
-    all_opt["boot_option"] = {
-        "getopt" : "b:",
-        "longopt" : "boot-option",
-        "help" : "-b, --boot-option=[option]     Change the default boot behavior of the machine. (pxe|hd|hdsafe|cd|diag)",
-        "required" : "0",
-        "shortdesc" : "Change the default boot behavior of the machine.",
-        "choices" : ["pxe", "hd", "hdsafe", "cd", "diag"],
-        "order" : 1
-        }
-    all_opt["amttool_path"] = {
-        "getopt" : "i:",
-        "longopt" : "amttool-path",
-        "help" : "--amttool-path=[path]          Path to amttool binary",
-        "required" : "0",
-        "shortdesc" : "Path to amttool binary",
-        "default" : "@AMTTOOL_PATH@",
-        "order": 200
-        }
+	all_opt["boot_option"] = {
+		"getopt" : "b:",
+		"longopt" : "boot-option",
+		"help" : "-b, --boot-option=[option]     "
+				"Change the default boot behavior of the machine. (pxe|hd|hdsafe|cd|diag)",
+		"required" : "0",
+		"shortdesc" : "Change the default boot behavior of the machine.",
+		"choices" : ["pxe", "hd", "hdsafe", "cd", "diag"],
+		"order" : 1
+	}
+	all_opt["amttool_path"] = {
+		"getopt" : ":",
+		"longopt" : "amttool-path",
+		"help" : "--amttool-path=[path]          Path to amttool binary",
+		"required" : "0",
+		"shortdesc" : "Path to amttool binary",
+		"default" : "@AMTTOOL_PATH@",
+		"order": 200
+	}
 
 def main():
+	atexit.register(atexit_handler)
 
-    atexit.register(atexit_handler)
+	device_opt = ["ipaddr", "no_login", "passwd", "boot_option", "no_port",
+		"sudo", "amttool_path", "method"]
 
-    device_opt = [ "ipaddr", "no_login", "passwd", "boot_option", "no_port",
-         "sudo", "amttool_path", "method" ]
+	define_new_opts()
 
-    define_new_opts()
+	all_opt["ipport"]["default"] = "16994"
 
-    options = check_input(device_opt, process_input(device_opt))
+	options = check_input(device_opt, process_input(device_opt))
 
-    docs = { }
-    docs["shortdesc"] = "Fence agent for AMT"
-    docs["longdesc"] = "fence_amt is an I/O Fencing agent \
+	docs = {}
+	docs["shortdesc"] = "Fence agent for AMT"
+	docs["longdesc"] = "fence_amt is an I/O Fencing agent \
 which can be used with Intel AMT. This agent calls support software amttool\
 (http://www.kraxel.org/cgit/amtterm/)."
-    docs["vendorurl"] = "http://www.intel.com/"
-    show_docs(options, docs)
+	docs["vendorurl"] = "http://www.intel.com/"
+	show_docs(options, docs)
+
+	run_delay(options)
 
-    if not is_executable(options["--amttool-path"]):
-        fail_usage("Amttool not found or not accessible")
+	if not is_executable(options["--amttool-path"]):
+		fail_usage("Amttool not found or not accessible")
 
-    result = fence_action(None, options, set_power_status, get_power_status, None, reboot_cycle)
+	result = fence_action(None, options, set_power_status, get_power_status, None, reboot_cycle)
 
-    sys.exit(result)
+	sys.exit(result)
 
 if __name__ == "__main__":
-    main()
+	main()
diff --git a/fence/agents/apc/Makefile.am b/fence/agents/apc/Makefile.am
index 355c873..051ac24 100644
--- a/fence/agents/apc/Makefile.am
+++ b/fence/agents/apc/Makefile.am
@@ -10,8 +10,8 @@ sbin_SCRIPTS		= $(TARGET)
 
 man_MANS		= $(TARGET).8
 
+FENCE_TEST_ARGS		= -l test -p test -a test -n 1
+
 include $(top_srcdir)/make/fencebuild.mk
 include $(top_srcdir)/make/fenceman.mk
-
-clean-local: clean-man
-	rm -f $(TARGET)
+include $(top_srcdir)/make/agentpycheck.mk
diff --git a/fence/agents/apc/fence_apc.py b/fence/agents/apc/fence_apc.py
index 24ab5ee..3307e4e 100644
--- a/fence/agents/apc/fence_apc.py
+++ b/fence/agents/apc/fence_apc.py
@@ -1,4 +1,4 @@
-#!/usr/bin/python
+#!/usr/bin/python -tt
 
 #####
 ##
@@ -10,13 +10,15 @@
 ##  AP7941      AOS v3.5.7, PDU APP v3.5.6
 ##  AP9606	AOS v2.5.4, PDU APP v2.7.3
 ##
-## @note: ssh is very slow on AP79XX devices protocol (1) and 
+## @note: ssh is very slow on AP79XX devices protocol (1) and
 ##        cipher (des/blowfish) have to be defined
 #####
 
-import sys, re, pexpect, exceptions
+import sys, re
+import atexit
 sys.path.append("@FENCEAGENTSLIBDIR@")
 from fencing import *
+from fencing import fail, fail_usage, EC_STATUS
 
 #BEGIN_VERSION_GENERATION
 RELEASE_VERSION="New APC Agent - test release on steroids"
@@ -29,27 +31,27 @@ def get_power_status(conn, options):
 	outlets = {}
 
 	conn.send_eol("1")
-	conn.log_expect(options, options["--command-prompt"], int(options["--shell-timeout"]))
+	conn.log_expect(options["--command-prompt"], int(options["--shell-timeout"]))
 
 	version = 0
 	admin = 0
 	switch = 0
 
-	if (None != re.compile('.* MasterSwitch plus.*', re.IGNORECASE | re.S).match(conn.before)):
+	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 None != re.compile('.* MasterSwitch plus 2', re.IGNORECASE | re.S).match(conn.before):
+			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)):
+	if None == re.compile('.*Outlet Management.*', re.IGNORECASE | re.S).match(conn.before):
 		version = 2
 	else:
 		version = 3
 
-	if (None == re.compile('.*Outlet Control/Configuration.*', re.IGNORECASE | re.S).match(conn.before)):
+	if None == re.compile('.*Outlet Control/Configuration.*', re.IGNORECASE | re.S).match(conn.before):
 		admin = 0
 	else:
 		admin = 1
@@ -62,25 +64,26 @@ def get_power_status(conn, options):
 				conn.send_eol("3")
 		else:
 			conn.send_eol("2")
-			conn.log_expect(options, options["--command-prompt"], int(options["--shell-timeout"]))
+			conn.log_expect(options["--command-prompt"], int(options["--shell-timeout"]))
 			conn.send_eol("1")
 	else:
 		conn.send_eol(options["--switch"])
-			
+
 	while True:
-		exp_result = conn.log_expect(options, ["Press <ENTER>" ] + options["--command-prompt"], int(options["--shell-timeout"]))
+		exp_result = conn.log_expect(
+				["Press <ENTER>"] + options["--command-prompt"], int(options["--shell-timeout"]))
 		lines = conn.before.split("\n")
-		show_re = re.compile('(^|\x0D)\s*(\d+)- (.*?)\s+(ON|OFF)\s*')
-		for x in lines:
-			res = show_re.search(x)
-			if (res != None):
+		show_re = re.compile(r'(^|\x0D)\s*(\d+)- (.*?)\s+(ON|OFF)\s*')
+		for line in lines:
+			res = show_re.search(line)
+			if res != None:
 				outlets[res.group(2)] = (res.group(3), res.group(4))
 		conn.send_eol("")
 		if exp_result != 0:
 			break
-	conn.send(chr(03))		
-	conn.log_expect(options, "- Logout", int(options["--shell-timeout"]))
-	conn.log_expect(options, options["--command-prompt"], int(options["--shell-timeout"]))
+	conn.send(chr(03))
+	conn.log_expect("- Logout", int(options["--shell-timeout"]))
+	conn.log_expect(options["--command-prompt"], int(options["--shell-timeout"]))
 
 	if ["list", "monitor"].count(options["--action"]) == 1:
 		return outlets
@@ -98,33 +101,33 @@ def set_power_status(conn, options):
 	}[options["--action"]]
 
 	conn.send_eol("1")
-	conn.log_expect(options, options["--command-prompt"], int(options["--shell-timeout"]))
+	conn.log_expect(options["--command-prompt"], int(options["--shell-timeout"]))
 
 	version = 0
 	admin2 = 0
 	admin3 = 0
 	switch = 0
 
-	if (None != re.compile('.* MasterSwitch plus.*', re.IGNORECASE | re.S).match(conn.before)):
+	if None != re.compile('.* MasterSwitch plus.*', re.IGNORECASE | re.S).match(conn.before):
 		switch = 1
 		## MasterSwitch has different schema for on/off actions
 		action = {
 			'on' : "1",
 			'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 None != re.compile('.* MasterSwitch plus 2', re.IGNORECASE | re.S).match(conn.before):
+			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)):
+	if None == re.compile('.*Outlet Management.*', re.IGNORECASE | re.S).match(conn.before):
 		version = 2
 	else:
 		version = 3
 
-	if (None == re.compile('.*Outlet Control/Configuration.*', re.IGNORECASE | re.S).match(conn.before)):
+	if None == re.compile('.*Outlet Control/Configuration.*', re.IGNORECASE | re.S).match(conn.before):
 		admin2 = 0
 	else:
 		admin2 = 1
@@ -137,8 +140,8 @@ def set_power_status(conn, options):
 				conn.send_eol("3")
 		else:
 			conn.send_eol("2")
-			conn.log_expect(options, options["--command-prompt"], int(options["--shell-timeout"]))
-			if (None == re.compile('.*2- Outlet Restriction.*', re.IGNORECASE | re.S).match(conn.before)):
+			conn.log_expect(options["--command-prompt"], int(options["--shell-timeout"]))
+			if None == re.compile('.*2- Outlet Restriction.*', re.IGNORECASE | re.S).match(conn.before):
 				admin3 = 0
 			else:
 				admin3 = 1
@@ -146,47 +149,47 @@ def set_power_status(conn, options):
 	else:
 		conn.send_eol(options["--switch"])
 
-	while 0 == conn.log_expect(options, [ "Press <ENTER>" ] + options["--command-prompt"], int(options["--shell-timeout"])):
+	while 0 == conn.log_expect(
+			["Press <ENTER>"] + options["--command-prompt"], int(options["--shell-timeout"])):
 		conn.send_eol("")
 
 	conn.send_eol(options["--plug"]+"")
-	conn.log_expect(options, options["--command-prompt"], int(options["--shell-timeout"]))
+	conn.log_expect(options["--command-prompt"], int(options["--shell-timeout"]))
 
 	if switch == 0:
 		if admin2 == 1:
 			conn.send_eol("1")
-			conn.log_expect(options, options["--command-prompt"], int(options["--shell-timeout"]))
+			conn.log_expect(options["--command-prompt"], int(options["--shell-timeout"]))
 		if admin3 == 1:
 			conn.send_eol("1")
-			conn.log_expect(options, options["--command-prompt"], int(options["--shell-timeout"]))
+			conn.log_expect(options["--command-prompt"], int(options["--shell-timeout"]))
 	else:
 		conn.send_eol("1")
-		conn.log_expect(options, options["--command-prompt"], int(options["--shell-timeout"]))
-		
+		conn.log_expect(options["--command-prompt"], int(options["--shell-timeout"]))
+
 	conn.send_eol(action)
-	conn.log_expect(options, "Enter 'YES' to continue or <ENTER> to cancel :", int(options["--shell-timeout"]))
+	conn.log_expect("Enter 'YES' to continue or <ENTER> to cancel :", int(options["--shell-timeout"]))
 	conn.send_eol("YES")
-	conn.log_expect(options, "Press <ENTER> to continue...", int(options["--shell-timeout"]))
+	conn.log_expect("Press <ENTER> to continue...", int(options["--power-timeout"]))
 	conn.send_eol("")
-	conn.log_expect(options, options["--command-prompt"], int(options["--shell-timeout"]))
+	conn.log_expect(options["--command-prompt"], int(options["--power-timeout"]))
 	conn.send(chr(03))
-	conn.log_expect(options, "- Logout", int(options["--shell-timeout"]))
-	conn.log_expect(options, options["--command-prompt"], int(options["--shell-timeout"]))
+	conn.log_expect("- Logout", int(options["--shell-timeout"]))
+	conn.log_expect(options["--command-prompt"], int(options["--shell-timeout"]))
 
 def get_power_status5(conn, options):
-	exp_result = 0
 	outlets = {}
 
 	conn.send_eol("olStatus all")
 
-	exp_result = conn.log_expect(options, options["--command-prompt"], int(options["--shell-timeout"]))
+	conn.log_expect(options["--command-prompt"], int(options["--shell-timeout"]))
 	lines = conn.before.split("\n")
-		
-	show_re = re.compile('^\s*(\d+): (.*): (On|Off)\s*$', re.IGNORECASE)
-	
-	for x in lines:
-		res = show_re.search(x)
-		if (res != None):
+
+	show_re = re.compile(r'^\s*(\d+): (.*): (On|Off)\s*$', re.IGNORECASE)
+
+	for line in lines:
+		res = show_re.search(line)
+		if res != None:
 			outlets[res.group(1)] = (res.group(2), res.group(3))
 
 	if ["list", "monitor"].count(options["--action"]) == 1:
@@ -205,20 +208,20 @@ def set_power_status5(conn, options):
 	}[options["--action"]]
 
 	conn.send_eol(action + " " + options["--plug"])
-	conn.log_expect(options, options["--command-prompt"], int(options["--power-timeout"]))
+	conn.log_expect(options["--command-prompt"], int(options["--power-timeout"]))
 
 def main():
-	device_opt = [  "ipaddr", "login", "passwd", "cmd_prompt", "secure", \
-			"port", "switch" ]
+	device_opt = ["ipaddr", "login", "passwd", "cmd_prompt", "secure", \
+			"port", "switch", "telnet"]
 
 	atexit.register(atexit_handler)
 
-	all_opt["cmd_prompt"]["default"] = [ "\n>", "\napc>" ]
+	all_opt["cmd_prompt"]["default"] = ["\n>", "\napc>"]
 	all_opt["ssh_options"]["default"] = "-1 -c blowfish"
 
 	options = check_input(device_opt, process_input(device_opt))
 
-	docs = { }
+	docs = {}
 	docs["shortdesc"] = "Fence agent for APC over telnet/ssh"
 	docs["longdesc"] = "fence_apc is an I/O Fencing agent \
 which can be used with the APC network power switch. It logs into device \
@@ -243,25 +246,13 @@ will block any necessary fencing actions."
 	## and continue with proper action
 	####
 	result = -1
-	firmware_version = re.compile('\s*v(\d)*\.').search(conn.before)
+	firmware_version = re.compile(r'\s*v(\d)*\.').search(conn.before)
 	if (firmware_version != None) and (firmware_version.group(1) == "5"):
 		result = fence_action(conn, options, set_power_status5, get_power_status5, get_power_status5)
 	else:
 		result = fence_action(conn, options, set_power_status, get_power_status, get_power_status)
 
-	##
-	## Logout from system
-	##
-	## In some special unspecified cases it is possible that 
-	## connection will be closed before we run close(). This is not 
-	## a problem because everything is checked before.
-	######
-	try:
-		conn.send_eol("4")
-		conn.close()
-	except:
-		pass
-	
+	fence_logout(conn, "4")
 	sys.exit(result)
 
 if __name__ == "__main__":
diff --git a/fence/agents/apc_snmp/Makefile.am b/fence/agents/apc_snmp/Makefile.am
index 65c24fd..258863c 100644
--- a/fence/agents/apc_snmp/Makefile.am
+++ b/fence/agents/apc_snmp/Makefile.am
@@ -2,18 +2,23 @@ MAINTAINERCLEANFILES	= Makefile.in
 
 TARGET			= fence_apc_snmp
 
+SYMTARGET		= fence_tripplite_snmp
+
 SRC			= $(TARGET).py
 
 EXTRA_DIST		= $(SRC) \
 			  powernet369.mib \
 			  README
 
-sbin_SCRIPTS		= $(TARGET)
+sbin_SCRIPTS		= $(TARGET) $(SYMTARGET)
+
+man_MANS		= $(TARGET).8 $(SYMTARGET).8
 
-man_MANS		= $(TARGET).8
+FENCE_TEST_ARGS         = -l test -p test -a test -n 1
 
 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)
+$(SYMTARGET): $(TARGET)
+	cp $^ $@
diff --git a/fence/agents/apc_snmp/fence_apc_snmp.py b/fence/agents/apc_snmp/fence_apc_snmp.py
index da02066..8bb3d48 100644
--- a/fence/agents/apc_snmp/fence_apc_snmp.py
+++ b/fence/agents/apc_snmp/fence_apc_snmp.py
@@ -1,18 +1,24 @@
-#!/usr/bin/python
+#!/usr/bin/python -tt
 
 # The Following agent has been tested on:
-# - APC Switched Rack PDU (MB:v3.7.0 PF:v2.7.0 PN:apc_hw02_aos_270.bin AF1:v2.7.3 AN1:apc_hw02_aos_270.bin
-#    AF1:v2.7.3 AN1:apc_hw02_rpdu_273.bin MN:AP7930 HR:B2) - SNMP v1
-# - APC Web/SNMP Management Card (MB:v3.8.6 PF:v3.5.8 PN:apc_hw02_aos_358.bin AF1:v3.5.7 AN1:apc_hw02_aos_358.bin
-#    AF1:v3.5.7 AN1:apc_hw02_rpdu_357.bin MN:AP7900 HR:B2) - SNMP v1 and v3 (noAuthNoPrivacy,authNoPrivacy, authPrivacy)
-# - APC Switched Rack PDU (MB:v3.7.0 PF:v2.7.0 PN:apc_hw02_aos_270.bin AF1:v2.7.3 AN1:apc_hw02_rpdu_273.bin
-#    MN:AP7951 HR:B2) - SNMP v1
+# - APC Switched Rack PDU - SNMP v1
+#	(MB:v3.7.0 PF:v2.7.0 PN:apc_hw02_aos_270.bin AF1:v2.7.3
+#	AN1:apc_hw02_aos_270.bin AF1:v2.7.3 AN1:apc_hw02_rpdu_273.bin MN:AP7930 HR:B2)
+# - APC Web/SNMP Management Card - SNMP v1 and v3 (noAuthNoPrivacy,authNoPrivacy, authPrivacy)
+#	(MB:v3.8.6 PF:v3.5.8 PN:apc_hw02_aos_358.bin AF1:v3.5.7
+#       AN1:apc_hw02_aos_358.bin AF1:v3.5.7 AN1:apc_hw02_rpdu_357.bin MN:AP7900 HR:B2)
+# - APC Switched Rack PDU - SNMP v1
+#       (MB:v3.7.0 PF:v2.7.0 PN:apc_hw02_aos_270.bin AF1:v2.7.3
+#       AN1:apc_hw02_rpdu_273.bin MN:AP7951 HR:B2)
 # - Tripplite PDUMH20HVNET 12.04.0055 - SNMP v1, v2c, v3
 
 import sys
+import atexit
+import logging
 sys.path.append("@FENCEAGENTSLIBDIR@")
 from fencing import *
-from fencing_snmp import *
+from fencing import fail_usage
+from fencing_snmp import FencingSnmp
 
 #BEGIN_VERSION_GENERATION
 RELEASE_VERSION="APC SNMP fence agent"
@@ -34,19 +40,19 @@ port_id = None
 switch_id = None
 
 # Classes describing Device params
-class TripplitePDU:
+class TripplitePDU(object):
         # Rack PDU
-        status_oid=      '.1.3.6.1.4.1.850.10.2.3.5.1.2.1.%d'
-        control_oid=     '.1.3.6.1.4.1.850.10.2.3.5.1.4.1.%d'
-        outlet_table_oid='.1.3.6.1.4.1.850.10.2.3.5.1.5'
-        ident_str="Tripplite"
-        state_on=2
-        state_off=1
-        turn_on=2
-        turn_off=1
-        has_switches=False
-
-class ApcRPDU:
+	status_oid =       '.1.3.6.1.4.1.850.10.2.3.5.1.2.1.%d'
+	control_oid =      '.1.3.6.1.4.1.850.10.2.3.5.1.4.1.%d'
+	outlet_table_oid = '.1.3.6.1.4.1.850.10.2.3.5.1.5'
+	ident_str = "Tripplite"
+	state_on = 2
+	state_off = 1
+	turn_on = 2
+	turn_off = 1
+	has_switches = False
+
+class ApcRPDU(object):
 	# Rack PDU
 	status_oid =       '.1.3.6.1.4.1.318.1.1.12.3.5.1.1.4.%d'
 	control_oid =      '.1.3.6.1.4.1.318.1.1.12.3.3.1.1.4.%d'
@@ -58,7 +64,7 @@ class ApcRPDU:
 	turn_off = 2
 	has_switches = False
 
-class ApcMSP:
+class ApcMSP(object):
 	# Master Switch+
 	status_oid =       '.1.3.6.1.4.1.318.1.1.6.7.1.1.5.%d.1.%d'
 	control_oid =      '.1.3.6.1.4.1.318.1.1.6.5.1.1.5.%d.1.%d'
@@ -70,7 +76,7 @@ class ApcMSP:
 	turn_off = 3
 	has_switches = True
 
-class ApcMS:
+class ApcMS(object):
 	# Master Switch - seems oldest, but supported on every APC PDU
 	status_oid =       '.1.3.6.1.4.1.318.1.1.4.4.2.1.3.%d'
 	control_oid =      '.1.3.6.1.4.1.318.1.1.4.4.2.1.3.%d'
@@ -82,75 +88,88 @@ class ApcMS:
 	turn_off = 2
 	has_switches = False
 
+class ApcMS6(object):
+	# Master Switch with 6.x firmware
+	status_oid = '.1.3.6.1.4.1.318.1.1.4.4.2.1.3.%d'
+	control_oid = '.1.3.6.1.4.1.318.1.1.12.3.3.1.1.4.%d'
+	outlet_table_oid = '1.3.6.1.4.1.318.1.1.4.4.2.1.4'
+	ident_str = "APC Master Switch with firmware v6.x"
+	state_on = 1
+	state_off = 2
+	turn_on = 1
+	turn_off = 2
+	has_switches = False
+
 ### FUNCTIONS ###
-def apc_set_device(conn, options):
+def apc_set_device(conn):
 	global device
 
 	agents_dir = {'.1.3.6.1.4.1.318.1.3.4.5':ApcRPDU,
 		    '.1.3.6.1.4.1.318.1.3.4.4':ApcMSP,
                     '.1.3.6.1.4.1.850.1':TripplitePDU,
+		    '.1.3.6.1.4.1.318.1.3.4.6':ApcMS6,
 		    None:ApcMS}
 
 	# First resolve type of APC
 	apc_type = conn.walk(OID_SYS_OBJECT_ID)
 
-	if (not ((len(apc_type)==1) and (agents_dir.has_key(apc_type[0][1])))):
+	if not ((len(apc_type) == 1) and (agents_dir.has_key(apc_type[0][1]))):
 		apc_type = [[None, None]]
 
 	device = agents_dir[apc_type[0][1]]
 
-	conn.log_command("Trying %s"%(device.ident_str))
+	logging.debug("Trying %s"%(device.ident_str))
 
 def apc_resolv_port_id(conn, options):
 	global port_id, switch_id
 
-	if (device == None):
-		apc_set_device(conn, options)
+	if device == None:
+		apc_set_device(conn)
 
 	# Now we resolv port_id/switch_id
-	if ((options["--plug"].isdigit()) and ((not device.has_switches) or (options["--switch"].isdigit()))):
+	if (options["--plug"].isdigit()) and ((not device.has_switches) or (options["--switch"].isdigit())):
 		port_id = int(options["--plug"])
 
-		if (device.has_switches):
+		if device.has_switches:
 			switch_id = int(options["--switch"])
 	else:
 		table = conn.walk(device.outlet_table_oid, 30)
 
 		for x in table:
-			if (x[1].strip('"') == options["--plug"]):
+			if x[1].strip('"') == options["--plug"]:
 				t = x[0].split('.')
-				if (device.has_switches):
+				if device.has_switches:
 					port_id = int(t[len(t)-1])
 					switch_id = int(t[len(t)-3])
 				else:
 					port_id = int(t[len(t)-1])
 
-	if (port_id == None):
+	if port_id == None:
 		fail_usage("Can't find port with name %s!"%(options["--plug"]))
 
 def get_power_status(conn, options):
-	if (port_id == None):
+	if port_id == None:
 		apc_resolv_port_id(conn, options)
 
 	oid = ((device.has_switches) and device.status_oid%(switch_id, port_id) or device.status_oid%(port_id))
 
 	(oid, status) = conn.get(oid)
-	return (status==str(device.state_on) and "on" or "off")
+	return status == str(device.state_on) and "on" or "off"
 
 def set_power_status(conn, options):
-	if (port_id == None):
+	if port_id == None:
 		apc_resolv_port_id(conn, options)
 
 	oid = ((device.has_switches) and device.control_oid%(switch_id, port_id) or device.control_oid%(port_id))
 
-	conn.set(oid, (options["--action"]=="on" and device.turn_on or device.turn_off))
+	conn.set(oid, (options["--action"] == "on" and device.turn_on or device.turn_off))
 
 
 def get_outlets_status(conn, options):
 	result = {}
 
-	if (device == None):
-		apc_set_device(conn, options)
+	if device == None:
+		apc_set_device(conn)
 
 	res_ports = conn.walk(device.outlet_table_oid, 30)
 
@@ -165,34 +184,29 @@ def get_outlets_status(conn, options):
 
 	return result
 
-# Define new options
-def apc_snmp_define_defaults():
-	all_opt["snmp_version"]["default"] = "1"
-	all_opt["community"]["default"] = "private"
-
 # Main agent method
 def main():
-	device_opt = [ "ipaddr", "login", "passwd", "no_login", "no_password", \
-		       "port", "snmp_version", "community" ]
+	device_opt = ["ipaddr", "login", "passwd", "no_login", "no_password", \
+		       "port", "snmp_version", "snmp"]
 
 	atexit.register(atexit_handler)
 
-	snmp_define_defaults ()
-	apc_snmp_define_defaults()
+	all_opt["snmp_version"]["default"] = "1"
+	all_opt["community"]["default"] = "private"
 
 	options = check_input(device_opt, process_input(device_opt))
 
         ## Support for -n [switch]:[plug] notation that was used before
-	if ((options.has_key("--plug")) and (-1 != options["--plug"].find(":"))):
+	if (options.has_key("--plug")) and (-1 != options["--plug"].find(":")):
 		(switch, plug) = options["--plug"].split(":", 1)
-		if ((switch.isdigit()) and (plug.isdigit())):
+		if switch.isdigit() and plug.isdigit():
 			options["--switch"] = switch
 			options["--plug"] = plug
 
-	if (not (options.has_key("--switch"))):
+	if not options.has_key("--switch"):
 		options["--switch"] = "1"
 
-	docs = { }
+	docs = {}
 	docs["shortdesc"] = "Fence agent for APC, Tripplite PDU over SNMP"
 	docs["longdesc"] = "fence_apc_snmp is an I/O Fencing agent \
 which can be used with the APC network power switch or Tripplite PDU devices.\
diff --git a/fence/agents/baytech/Makefile.am b/fence/agents/baytech/Makefile.am
deleted file mode 100644
index c0b0b84..0000000
--- a/fence/agents/baytech/Makefile.am
+++ /dev/null
@@ -1,17 +0,0 @@
-MAINTAINERCLEANFILES	= Makefile.in
-
-TARGET			= fence_baytech
-
-SRC			= $(TARGET).pl
-
-EXTRA_DIST		= $(SRC)
-
-sbin_SCRIPTS		= $(TARGET)
-
-man_MANS		= $(TARGET).8
-
-include $(top_srcdir)/make/fencebuild.mk
-include $(top_srcdir)/make/fencemanperl.mk
-
-clean-local: clean-man
-	rm -f $(TARGET)
diff --git a/fence/agents/baytech/fence_baytech.pl b/fence/agents/baytech/fence_baytech.pl
deleted file mode 100644
index bb7f42e..0000000
--- a/fence/agents/baytech/fence_baytech.pl
+++ /dev/null
@@ -1,746 +0,0 @@
-#!/usr/bin/perl
-
-# This fencing agent is written for the Baytech RPC27-20nc in conjunction with
-# a Cyclades terminal server.  The Cyclades TS exports the RPC's serial port
-# via a Telnet interface.  Other interfaces, such as SSH, are possible.  
-# However, this script relys upon the assumption that Telnet is used.  Future
-# features to this agent would allow the agent to work with a mulitude of 
-# different communication protocols such as Telnet, SSH or Kermit.
-#
-# The other assumption that is made is that Outlet names do not end in space.
-# The name "Foo" and "Foo    " are identical when the RPC prints them with
-# the status command.
-
-use Net::Telnet;
-use Getopt::Std;
-
-my $ME = $0;
-
-END {
-  defined fileno STDOUT or return;
-  close STDOUT and return;
-  warn "$ME: failed to close standard output: $!\n";
-  $? ||= 1;
-}
-
-# WARNING!! Do not add code bewteen "#BEGIN_VERSION_GENERATION" and 
-# "#END_VERSION_GENERATION"  It is generated by the Makefile
-
-#BEGIN_VERSION_GENERATION
-$RELEASE_VERSION="";
-$REDHAT_COPYRIGHT="";
-$BUILD_DATE="";
-#END_VERSION_GENERATION
-
-# Get the program name from $0 and strip directory names
-$_=$0;
-s/.*\///;
-my $pname = $_;
-
-
-sub rpc_error 
-{
-	if (defined $error_message && $error_message ne "")
-	{
-		chomp $error_message;
-		die "$error_message\n";
-	}
-	else
-	{
-		die "read timed-out\n"
-	}
-}
-
-sub usage 
-{
-
-    print "Usage:\n";
-    print "\n";
-    print "$pname [options]\n";
-    print "\n";
-    print "Options:\n";
-    print " -a host        host to connect to\n";
-    print " -D             debugging output\n";
-    print " -h             usage\n";
-    print " -l string      user name\n";
-    print " -o string      action: on,off,status, reboot (default) or metadata\n";
-    print " -n string      outlet name\n";
-    print " -p string      password\n";
-    print " -S path        script to run to retrieve password\n";
-    print " -V             version\n";
-
-    exit 0;
-}
-
-sub fail
-{
-  ($msg)=@_;
-  print $msg."\n" unless defined $quiet;
-  $t->close if defined $t;
-  exit 1;
-}
-
-sub fail_usage
-{
-  ($msg)=@_;
-  print STDERR $msg."\n" if $msg;
-  print STDERR "Please use '-h' for usage.\n";
-  exit 1;
-}
-
-sub version
-{
-  print "$pname $RELEASE_VERSION $BUILD_DATE\n";
-  print "$REDHAT_COPYRIGHT\n" if ( $REDHAT_COPYRIGHT );
-
-  exit 0;
-}
-
-sub print_metadata
-{
-print '<?xml version="1.0" ?>
-<resource-agent name="fence_baytech" shortdesc="I/O Fencing agent for Baytech RPC switches in combination with a Cyclades Terminal Server" >
-<longdesc>
-This fencing agent is written for the Baytech RPC27-20nc in  combination  with  a Cyclades  terminal server. The Cyclades TS exports the RPC\'s serial port via a Telnet interface.  Other interfaces, such as SSH, are  possible. However, this script relies upon the assumption that Telnet is used.  
-
-The  other assumption that is made is that Outlet names do not end in space. The name "Foo" and "Foo    " are identical when the RPC prints them with the status command.
-</longdesc>
-<vendor-url>http://www.baytech.net</vendor-url>
-<parameters>
-        <parameter name="action" unique="1" required="1">
-                <getopt mixed="-o [action]" />
-                <content type="string" default="disable" />
-                <shortdesc lang="en">Fencing Action</shortdesc>
-        </parameter>
-        <parameter name="ipaddr" unique="1" required="1">
-                <getopt mixed="-a [ip]" />
-                <content type="string"  />
-                <shortdesc lang="en">IP Address or Hostname</shortdesc>
-        </parameter>
-        <parameter name="login" unique="1" required="1">
-                <getopt mixed="-l [name]" />
-                <content type="string"  />
-                <shortdesc lang="en">Login Name</shortdesc>
-        </parameter>
-        <parameter name="passwd" unique="1" required="0">
-                <getopt mixed="-p [password]" />
-                <content type="string"  />
-                <shortdesc lang="en">Login password or passphrase</shortdesc>
-        </parameter>
-        <parameter name="passwd_script" unique="1" required="0">
-                <getopt mixed="-S [script]" />
-                <content type="string"  />
-                <shortdesc lang="en">Script to retrieve password</shortdesc>
-        </parameter>
-        <parameter name="port" unique="1" required="1">
-                <getopt mixed="-n [id]" />
-                <content type="string"  />
-                <shortdesc lang="en">Physical plug number or name of virtual machine</shortdesc>
-        </parameter>
-        <parameter name="help" unique="1" required="0">
-                <getopt mixed="-h" />
-                <content type="string"  />
-                <shortdesc lang="en">Display help and exit</shortdesc>
-        </parameter>
-</parameters>
-<actions>
-        <action name="enable" />
-        <action name="disable" />
-        <action name="status" />
-        <action name="metadata" />
-</actions>
-</resource-agent>
-';
-}
-
-
-# Get operating paramters, either with getopts or from STDIN
-sub get_options
-{
-   $action = "Reboot";
-   if (@ARGV > 0) {
-      getopts("n:l:p:S:o:a:VhD") || fail_usage ;
-
-      usage if defined $opt_h;
-      version if defined $opt_V;
-
-      fail_usage "Unkown parameter." if (@ARGV > 0);
-
-   } else {
-      get_options_stdin();
-   } 
-
-   if ((defined $opt_o) && ($opt_o =~ /metadata/i)) {
-      print_metadata();
-      exit 0;
-   }
-
-   fail "failed: must specify hostname" unless defined $opt_a;
-   $host=$opt_a;
-   $port=23 unless ($opt_a =~ /:/);
-
-   $action = $opt_o if defined $opt_o;
-   fail "failed: unrecognised action: $action"
-         unless $action=~ /^(Off|On|Reboot|status)$/i;
-   
-   fail "failed: no outletname" unless defined $opt_n;
-   $outlet = $opt_n;
-
-   $debug=$opt_D if defined $opt_D;
-   $quiet=$opt_q if defined $opt_q;
-   $user=$opt_l if defined $opt_l;
-   $passwd=$opt_p if defined $opt_p;
-   if (defined $opt_S) {
-     $pwd_script_out = `$opt_S`;
-     chomp($pwd_script_out);
-     if ($pwd_script_out) {
-       $passwd=$pwd_script_out;
-     }
-   }
-
-   if(defined $passwd && !defined $user)
-   {
-      fail "failed: password given without username";
-   }
-}
-
-# Get options from STDIN
-sub get_options_stdin
-{
-    my $opt;
-    my $line = 0;
-    while( defined($in = <>) )
-    {
-	$_ = $in;
-        chomp;
-
-	# strip leading and trailing whitespace
-        s/^\s*//;
-        s/\s*$//;
-
-	# skip comments
-	next if /^#/;
-
-        $line+=1;
-        $opt=$_;
-	next unless $opt;
-
-	($name,$val)=split /\s*=\s*/, $opt;
-
-	if ( $name eq "" )
-	{
-	   print STDERR "parse error: illegal name in option $line\n";
-	   exit 2;
-	} 
-
-        # DO NOTHING -- this field is used by fenced 
-	elsif ($name eq "agent" ) { } 
-
-	elsif ($name eq "host" ) 
-	{
-	    $opt_a = $val;
-	} 
-
-	elsif ($name eq "login" ) 
-	{
-	    $opt_l = $val;
-	} 
-
-	elsif ($name eq "passwd" ) 
-	{
-	    $opt_p = $val;
-	} 
-
-    elsif ($name eq "passwd_script") {
-        $opt_S = $val;
-    }
-
-	elsif ($name eq "action" ) 
-	{
-	    $opt_o = $val;
-	} 
-
-	elsif ($name eq "outlet" ) 
-	{
-	    $opt_n = $val;
-	} 
-
-    }
-}
-
-# Get a bunch of lines.  The newlines must terminate complete lines.
-sub getlines
-{
-	my $data=$t->get();
-	return undef unless defined $data;
-	my @chars = split //,$data;
-	my @lines;
-	my $line="";
-
-	for (my $i=0;$i<@chars;$i++)
-	{
-		$line = $line.$chars[$i];
-		next unless $chars[$i] eq "\n";
-		$lines[@lines] = $line;
-		$line = "";
-	}
-	$lines[@lines] = $line unless $line eq "";
-
-	return @lines;
-}
-
-# Fill the global input buffer of lines read.  All lines are terminated with
-# a newline.  If a line is not terminated, the next call to fill buffer will
-# append the last line of the input buffer with the first line that it gets from
-# getlines()
-sub fill_buffer
-{
-	my @lines = getlines();
-	return undef unless @lines;
-
-	if(@buffer)
-	{
-		if ( $buffer[$#buffer]=~/\n/) { }
-		else
-		{
-			$buffer[$#buffer] = $buffer[$#buffer].$lines[0];
-			shift @lines;
-		}
-	}
-
-	foreach (@lines) 
-	{ 
-		push @buffer,$_;
-	}
-}
-
-
-
-#
-# ($p_index, at data) = get_match @patterns;
-#
-# searches the input buffers for the patterns specified by the regeps in 
-# @patterns, when a match is found, all the lines through the matched 
-# pattern line are removed from the global input buffer and returned in the
-# array @data.  The index into @patterns for the matching pattern is also
-# returned.
-sub get_match
-{
-	my (@patterns) = @_;
-	$b_index = 0 unless defined $b_index;
-
-	fill_buffer() unless defined @buffer;
-
-	for(;;)
-	{
-		for(my $bi=$b_index; $bi<@buffer; $bi++)
-		{
-			for(my $pat=0; $pat<@patterns; $pat++)
-			{
-				if($buffer[$bi] =~ /$patterns[$pat]/)
-				{
-					$b_index = 0;
-					my @rtrn = splice(@buffer,0,$bi);
-					shift @buffer;
-				
-					if($debug)
-					{
-						foreach (@rtrn) { print $_ }
-						print "$patterns[$pat] ";
-					}
-					
-					return ($pat, at rtrn);
-				}
-			}
-			$b_index = $bi;
-		}
-
-		fill_buffer();
-	}
-}
-
-#
-# ($bt_num,$bt_name,$bt_state,$bt_locked) = parse_status $outlet, at data;
-#
-# This parses the data @data and searches for an outlet named $outlet.
-# The data will be in the form:
-# 
-#   Average Power:    0 Watts        Apparent Power:   17 VA
-# 
-#   True RMS Voltage: 120.0 Volts
-# 
-#   True RMS Current:   0.1 Amps     Maximum Detected:   0.2 Amps     
-# 
-#   Internal Temperature:  19.5 C
-# 
-#   Outlet Circuit Breaker: Good
-# 
-#    1)...Outlet  1       : Off           2)...Outlet  2       : Off          
-#    3)...Outlet  3       : On            4)...Outlet  4       : On           
-#    5)...Outlet  5       : On            6)...Outlet  6       : On           
-#    7)...Outlet  7       : On            8)...Outlet  8       : On           
-#    9)...Outlet  9       : On           10)...Outlet 10       : On           
-#   11)...Outlet 11       : On           12)...Outlet 12       : On           
-#   13)...Outlet 13       : On           14)...Outlet 14       : On           
-#   15)...Outlet 15       : On           16)...Outlet 16       : On           
-#   17)...Outlet 17       : On           18)...Outlet 18       : On           
-#   19)...Outlet 19       : On           20)...Outlet 20       : On    Locked 
-#
-sub parse_status
-{
-	my $outlet = shift;
-	my @data = @_;
-
-	my $bt_num="";
-	my $bt_name="";
-	my $bt_state="";
-	my $bt_locked="";
-
-	# Verify that the Outlet name exists
-	foreach my $line (@data)
-	{
-		next unless $line =~ /^[ 12][0-9]\)\.\.\./;
-
-		my @entries = split /([ 12][0-9])\)\.\.\./,$line;
-	
-		foreach my $entry (@entries)
-		{
-			next if $entry eq "";
-			
-			if($entry =~ /^([ 12][0-9])$/)
-			{
-				$bt_num = $1;
-			}
-			elsif($entry =~ /^(.{15}) : (On|Off)(.*)/)
-			{
-	
-				$bt_name = $1;
-				$bt_state = $2;
-				$bt_locked = $3;
-	
-				$_ = $bt_name;
-				s/\s*$//;
-				$bt_name = $_;
-	
-				$_ = $bt_locked;
-				s/\s*$//;
-				$bt_locked = $_;
-	
-				last if ($bt_name eq $outlet);
-	
-				$bt_name = "";
-				next;
-			}
-			else
-			{
-				die "parse error: $entry";
-			}
-		}
-		last if ($bt_name ne "");
-	}
-	
-	if ($bt_name eq "")
-	{
-		$bt_num=undef;
-		$bt_name=undef;
-		$bt_state=undef;
-		$bt_locked=undef;
-	}
-
-	return ($bt_num,$bt_name,$bt_state,$bt_locked);
-}
-
-##########################################################################
-#
-# Main
-
-get_options;
-
-
-if (defined $port)
-{
-	$t = new Net::Telnet(Host=>$host, Port=>$port) or 
-		die "Unable to connect to $host:$port: ".($!?$!:$_)."\n";
-}
-else
-{
-	$t = new Net::Telnet(Host=>$host) or 
-		die "Unable to connect to $host: ".($!?$!:$_)."\n";
-}
-
-
-
-#> DEBUG $t->dump_log("LOG");
-
-$t->print("\n");
-
-my @patterns;
-$prompt_user="^Enter user name:";
-$prompt_pass="^Enter Password:";
-$prompt_cmd="^RPC-27>";
-$prompt_confirm_yn="^.*\\(Y/N\\)\\?";
-
-$patterns[0]=$prompt_user;
-$patterns[1]=$prompt_pass;
-$patterns[2]=$prompt_cmd;
-$patterns[3]=$prompt_confirm_yn;
-
-my $p_index;
-my @data;
-
-my $bt_num="";
-my $bt_name="";
-my $bt_state="";
-my $bt_locked="";
-my $exit=1;
-
-($p_index, at data) = get_match @patterns;
-
-#
-# Set errmode after first get_match.  This allows for more descriptive errors
-# when handling unexpected error conditions
-#
-$t->errmode(\&rpc_error);
-
-# At this point, the username is unknown.  We'll just
-# pass in an empty passwd so that we can get back to the 
-# login prompt.  
-#
-# FIXME
-# If this is the third login failure for this switch, an
-# additional newline will need to be made sent.  This script
-# does not handle that case at this time.  This will cause
-# a timeout on read and cause this to fail.  Rerunning the
-# script ought to work though.
-if ($patterns[$p_index] eq $prompt_pass)
-{
-	$t->print("\n");
-	($p_index, at data) = get_match @patterns;
-}
-
-# Enter user name:
-#
-# Depending how the RPC is configured, a user name may not be required.
-# We will only deal with usernames if prompted.  
-#
-# If there is no user/passwd given as a parameter, but the switch
-# expects one, rather than just fail, we will first try to
-# get the switch in a known state 
-my $warn_user="yes";
-my $warn_passwd="yes";
-
-$error_message = "Invalid user/password";
-
-for (my $retrys=0; $patterns[$p_index] eq $prompt_user ; $retrys++)
-{
-	$warn_passwd = "yes";
-	if(defined $user)
-	{
-		$t->print("$user\n");
-		$warn_user = "no";
-	}
-	else
-	{
-		$t->print("\n");
-
-	}
-	($p_index, at data) = get_match @patterns;
-
-	# Enter Password:
-	#
-	# Users don't have to have passwords either.  We will only check
-	# that the user specified a password if we were prompted by the
-	# RPC.
-	if ($patterns[$p_index] eq $prompt_pass)
-	{
-		if(defined $passwd)
-		{
-			$t->print("$passwd\n");
-			$warn_passwd = "no";
-		}
-		else
-		{
-			$t->print("\n");
-		}
-
-		($p_index, at data) = get_match @patterns;
-	}
-
-
-	#
-	# If a valid user name is given, but not a valid password, we
-	# will loop forever unless we limit the number of retries
-	#
-	# set the user to "" so we stop entering a valid username and
-	# force the login proccess to fail
-	#
-	if ($retrys>2)
-	{
-		$user = "";
-	}
-	elsif ($retrys>10)
-	{
-		die "maximum retry count exceeded\n";
-	}
-}
-
-#
-# reset errmode to die()
-#
-$t->errmode("die");
-
-# all through with the login/passwd.  If we see any other prompt it is an 
-# error.
-if ($patterns[$p_index] ne $prompt_cmd)
-{
-	$t->print("\n");
-	die "bad state: '$patterns[$p_index]'";
-}
-
-if (defined $user && ($warn_user eq "yes"))
-{
-	warn "warning: user parameter ignored\n";
-}
-
-if (defined $passwd && ($warn_passwd eq "yes"))
-{
-	warn "warning: passwd parameter ignored\n";
-}
-
-
-
-
-# We are now logged in, no need for these patterns.  We'll strip these
-# so that we don't have to keep searching for patterns that shouldn't
-# appear.
-shift @patterns;
-shift @patterns;
-
-# Get the current status of a particular outlet.  Explicitly pass
-# the status command in case the RPC is not configured to report the
-# status on each command completion.
-$t->print("status\n");
-($p_index, at data) = get_match @patterns;
-($bt_num,$bt_name,$bt_state,$bt_locked) = parse_status $outlet, at data;
-
-if (!defined $bt_name )
-{
-	# We have problems if there is not outlet named $outlet
-	print "Outlet \'$outlet\' not found\n";
-	$exit=1;
-}
-elsif ($action =~ /status/i)
-{
-	print "Outlet '$bt_name' is $bt_state and is ".
-		(($bt_locked eq "")?"not ":"")."Locked\n";
-
-	if ($bt_state =~ /on/i)
-	{
-		$exit=0;
-	} else {
-		$exit=2;
-	}
-}
-elsif ($bt_locked ne "")
-{
-	# Report an error if an outlet is locked since we can't actually 
-	# issue commands on a Locked outlet.  This will prevent false
-	# successes.
-	print "Outlet '$bt_name' is Locked\n";
-	$exit=1;
-}
-elsif (($action =~ /on/i && $bt_state eq "On") ||
-	($action =~ /off/i && $bt_state eq "Off") )
-{
-	# No need to issue the on/off command since we are already in 
-	# the desired state
-	print "Outlet '$bt_name' is already $bt_state\n";
-	$exit=0;
-}
-elsif ($action =~ /o(n|ff)/i)
-{
-	# On/Off command
-	$t->print("$action $bt_num\n");
-	($p_index, at data) = get_match @patterns;
-	
-	# Confirmation prompting maybe enabled in the switch.  If it is,
-	# we enter 'Y' for yes.
-	if ($patterns[$p_index] eq $prompt_confirm_yn)
-	{
-		$t->print("y\n");
-		($p_index, at data) = get_match @patterns;
-	}
-
-	$t->print("status\n");
-	($p_index, at data) = get_match @patterns;
-
-	($bt_num,$bt_name,$bt_state,$bt_locked) = parse_status $outlet, at data;
-	
-	if ($bt_state =~ /$action/i)
-	{
-		print "success: outlet='$outlet' action='$action'\n";
-		$exit=0;
-	}
-	else
-	{	
-		print "fail: outlet='$outlet' action='$action'\n";
-		$exit=1;
-	}
-}
-elsif ($action =~ /reboot/i)
-{
-	# Reboot command
-	$t->print("$action $bt_num\n");
-	($p_index, at data) = get_match @patterns;
-	
-	# Confirmation prompting maybe enabled in the switch.  If it is,
-	# we enter 'Y' for yes.
-	if ($patterns[$p_index] eq $prompt_confirm_yn)
-	{
-		$t->print("y\n");
-		($p_index, at data) = get_match @patterns;
-	}
-
-	# The reboot command is annoying.  It reports that the outlet will
- 	# reboot in 9 seconds.  Then it has a countdown timer.  We first
-	# look for the "Rebooting... 9" message, then we parse the remaining
-	# output to verify that it reaches 0 without skipping anything.
-	my $pass=0;
-	foreach (@data)
-	{
-		chomp;
-		my $line = $_;
-
-		# There is a countdown timer that prints a number, then sleeps a 
-		# second, then prints a backspace and then another number
-		#
-		# /^Rebooting\.\.\. 9\b8\b7\b6\b5\b4\b3\b2\b1\b0\b$/
-		if($line =~/^Rebooting\.\.\..*0[\b]$/)
-		{
-			$pass=1;
-			last;
-		}
-	}
-
-	if ($pass)
-	{
-		print "success: outlet='$outlet' action='$action'\n";
-		$exit=0;
-	}
-	else
-	{
-		print "fail: outlet='$outlet' action='$action'\n";
-		$exit=1;
-	}
-}
-else
-{
-	die "bad state";
-}
-
-# Clean up.  If we don't tell it to logout, then anybody else can log onto 
-# the serial port and have access to the switch without authentication (when 
-# enabled)
-$t->print("logout\n");
-$t->close;
-exit $exit;
diff --git a/fence/agents/bladecenter/Makefile.am b/fence/agents/bladecenter/Makefile.am
index d910196..09358b5 100644
--- a/fence/agents/bladecenter/Makefile.am
+++ b/fence/agents/bladecenter/Makefile.am
@@ -10,8 +10,8 @@ sbin_SCRIPTS		= $(TARGET)
 
 man_MANS		= $(TARGET).8
 
+FENCE_TEST_ARGS         = -l test -p test -a test -n 1
+
 include $(top_srcdir)/make/fencebuild.mk
 include $(top_srcdir)/make/fenceman.mk
-
-clean-local: clean-man
-	rm -f $(TARGET)
+include $(top_srcdir)/make/agentpycheck.mk
diff --git a/fence/agents/bladecenter/fence_bladecenter.py b/fence/agents/bladecenter/fence_bladecenter.py
index 14a152b..d72c07f 100644
--- a/fence/agents/bladecenter/fence_bladecenter.py
+++ b/fence/agents/bladecenter/fence_bladecenter.py
@@ -1,4 +1,4 @@
-#!/usr/bin/python
+#!/usr/bin/python -tt
 
 #####
 ##
@@ -6,15 +6,17 @@
 ##
 ##  Model                 Firmware
 ## +--------------------+---------------------------+
-## (1) Main application	  BRET85K, rev 16  
+## (1) Main application	  BRET85K, rev 16
 ##     Boot ROM           BRBR67D, rev 16
 ##     Remote Control     BRRG67D, rev 16
 ##
 #####
 
-import sys, re, pexpect, exceptions
+import sys, re
+import atexit
 sys.path.append("@FENCEAGENTSLIBDIR@")
 from fencing import *
+from fencing import fail, EC_STATUS, EC_GENERIC_ERROR
 
 #BEGIN_VERSION_GENERATION
 RELEASE_VERSION="New Bladecenter Agent - test release on steroids"
@@ -23,10 +25,10 @@ BUILD_DATE="March, 2008"
 #END_VERSION_GENERATION
 
 def get_power_status(conn, options):
-	node_cmd = "system:blade\[" + options["--plug"] + "\]>"
+	node_cmd = r"system:blade\[" + options["--plug"] + r"\]>"
 
 	conn.send_eol("env -T system:blade[" + options["--plug"] + "]")
-	i = conn.log_expect(options, [ node_cmd, "system>" ] , int(options["--shell-timeout"]))
+	i = conn.log_expect([node_cmd, "system>"], int(options["--shell-timeout"]))
 	if i == 1:
 		## Given blade number does not exist
 		if options.has_key("--missing-as-off"):
@@ -34,18 +36,18 @@ def get_power_status(conn, options):
 		else:
 			fail(EC_STATUS)
 	conn.send_eol("power -state")
-	conn.log_expect(options, node_cmd, int(options["--shell-timeout"]))
+	conn.log_expect(node_cmd, int(options["--shell-timeout"]))
 	status = conn.before.splitlines()[-1]
 	conn.send_eol("env -T system")
-	conn.log_expect(options, options["--command-prompt"], int(options["--shell-timeout"]))
+	conn.log_expect(options["--command-prompt"], int(options["--shell-timeout"]))
 
 	return status.lower().strip()
 
 def set_power_status(conn, options):
-	node_cmd = "system:blade\[" + options["--plug"] + "\]>"
+	node_cmd = r"system:blade\[" + options["--plug"] + r"\]>"
 
 	conn.send_eol("env -T system:blade[" + options["--plug"] + "]")
-	i = conn.log_expect(options, [ node_cmd, "system>" ] , int(options["--shell-timeout"]))
+	i = conn.log_expect([node_cmd, "system>"], int(options["--shell-timeout"]))
 	if i == 1:
 		## Given blade number does not exist
 		if options.has_key("--missing-as-off"):
@@ -54,22 +56,22 @@ def set_power_status(conn, options):
 			fail(EC_GENERIC_ERROR)
 
 	conn.send_eol("power -"+options["--action"])
-	conn.log_expect(options, node_cmd, int(options["--shell-timeout"]))
+	conn.log_expect(node_cmd, int(options["--shell-timeout"]))
 	conn.send_eol("env -T system")
-	conn.log_expect(options, options["--command-prompt"], int(options["--shell-timeout"]))
+	conn.log_expect(options["--command-prompt"], int(options["--shell-timeout"]))
 
 def get_blades_list(conn, options):
-	outlets = { }
+	outlets = {}
 
 	node_cmd = "system>"
 
 	conn.send_eol("env -T system")
-	conn.log_expect(options, node_cmd, int(options["--shell-timeout"]))
+	conn.log_expect(node_cmd, int(options["--shell-timeout"]))
 	conn.send_eol("list -l 2")
-	conn.log_expect(options, node_cmd, int(options["--shell-timeout"]))
+	conn.log_expect(node_cmd, int(options["--shell-timeout"]))
 
 	lines = conn.before.split("\r\n")
-	filter_re = re.compile("^\s*blade\[(\d+)\]\s+(.*?)\s*$")
+	filter_re = re.compile(r"^\s*blade\[(\d+)\]\s+(.*?)\s*$")
 	for blade_line in lines:
 		res = filter_re.search(blade_line)
 		if res != None:
@@ -78,17 +80,17 @@ def get_blades_list(conn, options):
 	return outlets
 
 def main():
-	device_opt = [  "ipaddr", "login", "passwd", "cmd_prompt", "secure", \
-			"port", "missing_as_off" ]
+	device_opt = ["ipaddr", "login", "passwd", "cmd_prompt", "secure", \
+			"port", "missing_as_off", "telnet"]
 
 	atexit.register(atexit_handler)
 
 	all_opt["power_wait"]["default"] = "10"
-	all_opt["cmd_prompt"]["default"] = [ "system>" ]
+	all_opt["cmd_prompt"]["default"] = ["system>"]
 
 	options = check_input(device_opt, process_input(device_opt))
 
-	docs = { }        
+	docs = {}
 	docs["shortdesc"] = "Fence agent for IBM BladeCenter"
 	docs["longdesc"] = "fence_bladecenter is an I/O Fencing agent \
 which can be used with IBM Bladecenters with recent enough firmware that \
@@ -96,22 +98,13 @@ includes telnet support. It logs into a Brocade chasis via telnet or ssh \
 and uses the command line interface to power on and off blades."
 	docs["vendorurl"] = "http://www.ibm.com"
 	show_docs(options, docs)
-	
+
 	##
 	## Operate the fencing device
 	######
-	conn = fence_login(options, "(username: )")
+	conn = fence_login(options, "(username\s*:\s*)")
 	result = fence_action(conn, options, set_power_status, get_power_status, get_blades_list)
-
-	##
-	## Logout from system
-	######
-	try:
-		conn.send_eol("exit")
-		conn.close()
-	except:
-		pass
-	
+	fence_logout(conn, "exit")
 	sys.exit(result)
 
 if __name__ == "__main__":
diff --git a/fence/agents/brocade/Makefile.am b/fence/agents/brocade/Makefile.am
index 171425f..6ff704d 100644
--- a/fence/agents/brocade/Makefile.am
+++ b/fence/agents/brocade/Makefile.am
@@ -10,8 +10,8 @@ sbin_SCRIPTS		= $(TARGET)
 
 man_MANS		= $(TARGET).8
 
+FENCE_TEST_ARGS         = -l test -p test -a test -n 1
+
 include $(top_srcdir)/make/fencebuild.mk
 include $(top_srcdir)/make/fenceman.mk
-
-clean-local: clean-man
-	rm -f $(TARGET)
+include $(top_srcdir)/make/agentpycheck.mk
diff --git a/fence/agents/brocade/fence_brocade.py b/fence/agents/brocade/fence_brocade.py
index 25581fd..e5a5063 100644
--- a/fence/agents/brocade/fence_brocade.py
+++ b/fence/agents/brocade/fence_brocade.py
@@ -1,8 +1,10 @@
-#!/usr/bin/python
+#!/usr/bin/python -tt
 
-import sys, re, pexpect, exceptions
+import sys, re
+import atexit
 sys.path.append("@FENCEAGENTSLIBDIR@")
 from fencing import *
+from fencing import fail, EC_STATUS
 
 #BEGIN_VERSION_GENERATION
 RELEASE_VERSION="New Brocade Agent - test release on steroids"
@@ -10,24 +12,6 @@ REDHAT_COPYRIGHT=""
 BUILD_DATE="March, 20013"
 #END_VERSION_GENERATION
 
-def get_power_status(conn, options):
-	conn.send_eol("portCfgShow " + options["--plug"])
-
-	exp_result = conn.log_expect(options, options["--command-prompt"], int(options["--shell-timeout"]))
-
-	show_re = re.compile('^\s*Persistent Disable\s*(ON|OFF)\s*$', re.IGNORECASE)
-	lines = conn.before.split("\n")
-
-	for x in lines:
-		res = show_re.search(x)
-		if (res != None):
-			# We queried if it is disabled, so we have to negate answer
-			if res.group(1) == "ON":
-				return "off"
-			else:
-				return "on"
-
-	fail(EC_STATUS)
 def set_power_status(conn, options):
 	action = {
 		'on' : "portCfgPersistentEnable",
@@ -35,19 +19,41 @@ def set_power_status(conn, options):
 	}[options["--action"]]
 
 	conn.send_eol(action + " " + options["--plug"])
-	conn.log_expect(options, options["--command-prompt"], int(options["--power-timeout"]))
+	conn.log_expect(options["--command-prompt"], int(options["--power-timeout"]))
+
+def get_power_status(conn, options):
+	line_re = re.compile(r'=========', re.IGNORECASE)
+	outlets = {}
+	in_index = False
+
+	conn.send_eol("switchshow")
+	conn.log_expect(options["--command-prompt"], int(options["--power-timeout"]))
+	for line in str(conn.before).split("\n"):
+		if line_re.search(line):
+			in_index = True
+		elif in_index and line.lstrip()[0].isdigit():
+			tokens = line.lstrip().split()
+			status = "off" if len(tokens) > 7 and tokens[7] == "Disabled" else "on"
+			outlets[tokens[0]] = ("", status)
+
+	if options["--action"] == "status":
+		(_, status) = outlets[options["--plug"]]
+		return status
+	else:
+		return outlets
 
 def main():
-	device_opt = [  "ipaddr", "login", "passwd", "cmd_prompt", "secure", "port", "fabric_fencing" ]
+	device_opt = ["ipaddr", "login", "passwd", "cmd_prompt", "secure", \
+		"port", "fabric_fencing", "telnet"]
 
 	atexit.register(atexit_handler)
 
-	all_opt["cmd_prompt"]["default"] = [ "> " ]
+	all_opt["cmd_prompt"]["default"] = ["> "]
 
 	options = check_input(device_opt, process_input(device_opt))
 	options["eol"] = "\n"
 
-	docs = { }
+	docs = {}
 	docs["shortdesc"] = "Fence agent for HP Brocade over telnet/ssh"
 	docs["longdesc"] = "fence_brocade is an I/O Fencing agent which can be used with Brocade FC switches. \
 It logs into a Brocade switch via telnet and disables a specified port. Disabling the port which a machine is \
@@ -64,22 +70,8 @@ FC switch needs to be enabled. This can be done by running fence_brocade and spe
 	## Operate the fencing device
 	####
 	conn = fence_login(options)
-
-	result = fence_action(conn, options, set_power_status, get_power_status, None)
-
-	##
-	## Logout from system
-	##
-	## In some special unspecified cases it is possible that 
-	## connection will be closed before we run close(). This is not 
-	## a problem because everything is checked before.
-	######
-	try:
-		conn.send_eol("exit")
-		conn.close()
-	except:
-		pass
-	
+	result = fence_action(conn, options, set_power_status, get_power_status, get_power_status)
+	fence_logout(conn, "exit")
 	sys.exit(result)
 
 if __name__ == "__main__":
diff --git a/fence/agents/bullpap/Makefile.am b/fence/agents/bullpap/Makefile.am
deleted file mode 100644
index a602b5e..0000000
--- a/fence/agents/bullpap/Makefile.am
+++ /dev/null
@@ -1,17 +0,0 @@
-MAINTAINERCLEANFILES	= Makefile.in
-
-TARGET			= fence_bullpap
-
-SRC			= $(TARGET).pl
-
-EXTRA_DIST		= $(SRC)
-
-sbin_SCRIPTS		= $(TARGET)
-
-man_MANS		= $(TARGET).8
-
-include $(top_srcdir)/make/fencebuild.mk
-include $(top_srcdir)/make/fencemanperl.mk
-
-clean-local: clean-man
-	rm -f $(TARGET)
diff --git a/fence/agents/bullpap/fence_bullpap.pl b/fence/agents/bullpap/fence_bullpap.pl
deleted file mode 100644
index 3012fa2..0000000
--- a/fence/agents/bullpap/fence_bullpap.pl
+++ /dev/null
@@ -1,433 +0,0 @@
-#!/usr/bin/perl
-
-use Getopt::Std;
-use POSIX;
-
-my $ME = $0;
-
-END {
-  defined fileno STDOUT or return;
-  close STDOUT and return;
-  warn "$ME: failed to close standard output: $!\n";
-  $? ||= 1;
-}
-
-# Get the program name from $0 and strip directory names
-$_=$0;
-s/.*\///;
-my $pname = $_;
-
-$action = "reboot"; # Default fence action
-my $bulldir = "/usr/local/bull/NSMasterHW/bin";
-
-
-# WARNING!! Do not add code bewteen "#BEGIN_VERSION_GENERATION" and 
-# "#END_VERSION_GENERATION"  It is generated by the Makefile
-
-#BEGIN_VERSION_GENERATION
-$RELEASE_VERSION="";
-$REDHAT_COPYRIGHT="";
-$BUILD_DATE="";
-#END_VERSION_GENERATION
-
-
-sub usage
-{
-	print "Usage:\n";
-	print "\n";
-	print "$pname [options]\n";
-	print "\n";
-	print "Options:\n";
-	print "  -a <ip>          IP address or hostname of PAP console\n";
-	print "  -h               usage\n";
-	print "  -l <name>        Login name\n";
-	print "  -d <domain>      Domain to operate on\n";
-	print "  -o <string>      Action:  on, off, reboot (default), status or metadata\n";
-	print "  -p <string>      Password for login\n";
-	print "  -S <path>        Script to run to retrieve password\n";
-	print "  -q               quiet mode\n";
-	print "  -V               version\n";
-	print "\n";
-	print "When run with no arguments, $pname takes arguments from ";
-	print "standard\ninput, one line per option.  They are as follows:\n";
-	print "\n";
-	print "  ipaddr=<ip>          Same as -a command line option\n";
-	print "  login=<name>         Same as -l command line option\n";
-	print "  domain=<domain>      Same as -d command line option\n";
-	print "  option=<string>      Same as -o command line option\n";
-	print "  passwd=<string>      Same as -p command line option\n";
-	print "  passwd_script=<path> Same as -S command line option\n\n";
-
-	exit 0;
-}
-
-sub fail
-{
-	($msg) = @_;
-	print $msg."\n" unless defined $quiet;
-	exit 1;
-}
-
-sub fail_usage
-{
-	($msg)=@_;
-	print STDERR $msg."\n" if $msg;
-	print STDERR "Please use '-h' for usage.\n";
-	exit 1;
-}
-
-sub version
-{
-	print "$pname $RELEASE_VERSION $BUILD_DATE\n";
-	print "$REDHAT_COPYRIGHT\n" if ( $REDHAT_COPYRIGHT );
-
-	exit 0;
-}
-
-sub print_metadata
-{
-print '<?xml version="1.0" ?>
-<resource-agent name="fence_bullpap" shortdesc="I/O Fencing agent for Bull FAME architecture controlled by a PAP management console." >
-<longdesc>
-fence_bullpap is an I/O Fencing agent which can be used with Bull\'s NovaScale machines controlled by PAP management consoles. This agent calls Bull\'s support software provided by the NSMasterHW RPM available from Bull.
-</longdesc>
-<vendor-url>http://www.bull.com</vendor-url>
-<parameters>
-        <parameter name="action" unique="1" required="1">
-                <getopt mixed="-o [action]" />
-                <content type="string" default="reboot" />
-                <shortdesc lang="en">Fencing Action</shortdesc>
-        </parameter>
-        <parameter name="ipaddr" unique="1" required="1">
-                <getopt mixed="-a [ip]" />
-                <content type="string"  />
-                <shortdesc lang="en">IP Address or Hostname</shortdesc>
-        </parameter>
-        <parameter name="login" unique="1" required="1">
-                <getopt mixed="-l [name]" />
-                <content type="string"  />
-                <shortdesc lang="en">Login Name</shortdesc>
-        </parameter>
-        <parameter name="passwd" unique="1" required="0">
-                <getopt mixed="-p [password]" />
-                <content type="string"  />
-                <shortdesc lang="en">Login password or passphrase</shortdesc>
-        </parameter>
-        <parameter name="passwd_script" unique="1" required="0">
-                <getopt mixed="-S [script]" />
-                <content type="string"  />
-                <shortdesc lang="en">Script to retrieve password</shortdesc>
-        </parameter>
-        <parameter name="domain" unique="1" required="1">
-                <getopt mixed="-d [domain]" />
-                <content type="string"  />
-                <shortdesc lang="en">Domain name of the Bull machine to power-cycle</shortdesc>
-        </parameter>
-        <parameter name="help" unique="1" required="0">
-                <getopt mixed="-h" />           
-                <content type="string"  />
-                <shortdesc lang="en">Display help and exit</shortdesc>                    
-        </parameter>
-</parameters>
-<actions>
-        <action name="on" />
-        <action name="off" />
-	<action name="reboot" />
-        <action name="status" />
-        <action name="metadata" />
-</actions>
-</resource-agent>
-';
-}
-
-sub get_options_stdin
-{
-	my $opt;
-	my $line = 0;
-	while( defined($in = <>) )
-	{
-		$_ = $in;
-		chomp;
-
-		# strip leading and trailing whitespace
-		s/^\s*//;
-		s/\s*$//;
-	
-		# skip comments
-		next if /^#/;
-
-		$line+=1;
-		$opt=$_;
-		next unless $opt;
-
-		($name,$val)=split /\s*=\s*/, $opt;
-
-		if ( $name eq "" )
-		{  
-			print STDERR "parse error: illegal name in option $line\n";
-			exit 2;
-		}
-	
-		# DO NOTHING -- this field is used by fenced
-		elsif ($name eq "agent" ) { } 
-
-		elsif ($name eq "ipaddr" ) 
-		{
-			$host = $val;
-		} 
-		elsif ($name eq "login" ) 
-		{
-			$login = $val;
-		} 
-		elsif (($name eq "option" ) || ($name eq "action"))
-		{
-			$action = $val;
-		}
-		elsif ($name eq "passwd" ) 
-		{
-			$passwd = $val;
-		} 
-		elsif ($name eq "password" ) 
-		{
-			$passwd = $val;
-		} 
-		elsif ($name eq "passwd_script" ) {
-			$passwd_script = $val;
-		}
-		elsif ($name eq "domain" ) 
-		{
-			$domain = $val;
-		} 
-		elsif ($name eq "debuglog" ) 
-		{
-			$verbose = $val;
-		} 
-	}
-}
-
-sub get_power_state
-{
-	my ($ip,$dom,$user,$pass,$junk) = @_;
-	fail "missing IP address in get_power_state()" unless defined $ip;
-	fail "missing domain to get_power_state()" unless defined $dom;
-	fail "illegal argument to get_power_state()" if defined $junk;
-
-	my $state="";
-	my $cmd = $bulldir . "/pampower.pl";
-	
-	$cmd = $cmd . " -a status";
-	$cmd = $cmd . " -M $ip -D $dom";
-	if (defined $user) {
-		$cmd = $cmd . "	-u $user";
-	}
-	if (defined $pass) {
-		$cmd = $cmd . " -p $pass";
-	}
-
-	$state=system($cmd);
-	WIFEXITED($state) || die "child killed abnormally";
-
-	$state=WEXITSTATUS($state);
-	if ($state == 0) {
-		$state = "ON";
-	} elsif ($state == 1) {
-		$state = "OFF";
-	} else {
-		$state = "$state TRANSITION";
-	}
-
-	$_=$state;
-}
-
-sub set_power_state
-{
-	my ($ip,$dom,$set,$user,$pass,$junk) = @_;
-	fail "missing action to set_power_state()" unless defined $set;
-	fail "missing IP address in set_power_state()" unless defined $ip;
-	fail "missing domain to set_power_state()" unless defined $dom;
-	fail "illegal argument to set_power_state()" if defined $junk;
-
-	my $state="";
-	my $cmd = $bulldir . "/pampower.pl";
-	
-	if ($set =~ /on/) {
-		$cmd = $cmd . " -a on";
-	} else {
-		$cmd = $cmd . " -a off_force";
-	}
-	
-	$cmd = $cmd . " -M $ip -D $dom";
-	if (defined $user) {
-		$cmd = $cmd . "	-u $user";
-	}
-	if (defined $pass) {
-		$cmd = $cmd . " -p $pass";
-	}
-
-	$state=system "$cmd";
-
-	$_=$state;
-}
-
-# MAIN
-
-if (@ARGV > 0) 
-{
-	getopts("a:hl:d:o:p:S:qv:V") || fail_usage ;
-
-	usage if defined $opt_h;
-	version if defined $opt_V;
-
-	if ((defined $opt_o) && ($opt_o =~ /metadata/i)) {
-		print_metadata();
-		exit 0;
-	}
-
-	$host     = $opt_a if defined $opt_a;
-	$login    = $opt_l if defined $opt_l;
-	$passwd   = $opt_p if defined $opt_p;
-	$action   = $opt_o if defined $opt_o;
-	$domain	  = $opt_d if defined $opt_d;
-	$verbose  = $opt_v if defined $opt_v;
-	$quiet    = $opt_q if defined $opt_q;
-
-	if (defined $opt_S) {
-		$pwd_script_out = `$opt_S`;
-		chomp($pwd_script_out);
-		if ($pwd_script_out) {
-			$passwd = $pwd_script_out;
-		}
-	}
-
-	fail_usage "Unknown parameter." if (@ARGV > 0);
-
-	fail_usage "No '-a' flag specified." unless defined $host;
-	fail_usage "No '-d' flag specified." unless defined $domain;
-	fail_usage "No '-l' flag specified." unless defined $login;
-	fail_usage "No '-p' or '-S' flag specified." unless defined $passwd;
-	fail_usage "Unrecognised action '$action' for '-o' flag"
-		unless $action =~ /^(on|off|reboot|status)$/i;
-} 
-else 
-{
-	get_options_stdin();
-
-	if ((defined $action) && ($action =~ /metadata/i)) {
-		print_metadata();
-		exit 0;
-	}
-
-	fail "failed: no IP address" unless defined $host;
-	fail "failed: no domain" unless defined $domain;
-	fail "failed: no login name" unless defined $login;
-	fail "failed: unrecognized action: $action"
-		unless $action =~ /^(on|off|reboot|status)$/i;
-
-	if (defined $passwd_script) {
-		$pwd_script_out = `$passwd_script`;
-		chomp($pwd_script_out);
-		if ($pwd_script_out) {
-			$passwd = $pwd_script_out;
-		}
-	}
-	fail "failed: no password" unless defined $passwd;
-}
-
-stat($bulldir);
-die "NSMasterHW not installed correctly" if ! -d _;
-
-# convert $action to lower case 
-$_=$action;
-if    (/^on$/i)     { $action = "on"; }
-elsif (/^off$/i)    { $action = "off"; }
-elsif (/^reboot$/i) { $action = "reboot"; }
-elsif (/^status$/i) { $action = "status"; }
-
-#
-# If if pampower / pamreset don't exist, we're done.
-#
-# -M -- the maintenance port on the NovaScale Windows 2000 master server
-# -D -- the Domain to reboot
-# -u -- User name
-# -p -- Password
-#
-#/usr/local/bull/NSMasterHW/bin/pamreset.pl 
-#    -M 192.168.78.169 -D Domaine2-8CPU -u Administrator -p administrator
-#
-#/usr/local/bull/NSMasterHW/bin/pampower.pl -a off_force 
-#    -M 192.168.78.169 -D Domaine2-8CPU -u Administrator -p administrator
-#
-#/usr/local/bull/NSMasterHW/bin/pampower.pl -a on 
-#    -M 192.168.78.169 -D Domaine2-8CPU -u Administrator -p administrator
-#
-# Do the command
-#
-$success=0;
-$_ = $action;
-my $exit_code=0;
-if (/(on|off)/)
-{
-	my $timeout = 120; # 120 = max of (60, 120).  Max timeout for "on"
-			   # on 32-way bull machines
-
-	set_power_state $host,$domain,$action,$login,$passwd;
-	do {
-		sleep 5;
-		$state=get_power_state $host,$domain,$login,$passwd;
-		$timeout -= 5;
-	} while ($timeout > 0 && !($state =~ /^$action$/i));
-
-	$success = 1 if ($state=~/^$action$/i);
-}
-elsif (/reboot/)
-{
-	my $timeout = 60; # 60 seconds for "off" for 32-way bull machines
-
-	set_power_state $host,$domain,"off",$login,$passwd;
-	do {
-		sleep 5;
-		$state=get_power_state $host,$domain,$login,$passwd;
-		$timeout -= 5;
-	} while ($timeout > 0 && $state != 0);
-
-	if ($timeout <= 0) {
-		$success = 0;
-	} else  {
-		$timeout = 120; # 120 seconds for on, for 32-way bull machines
-		set_power_state $host,$domain,"on",$login,$passwd;
-		do {
-			sleep 5;
-			$state=get_power_state $host,$domain,$login,$passwd;
-			$timeout -= 5;
-		} while ($timeout > 0 && $state != 0);
-
-		$success = 1 if ($state == 0);
-	}
-}
-elsif (/status/)
-{
-	get_power_state $host,$domain,$login,$passwd;
-	$state=$_;
-	$success = 1 if defined $state;
-	if ($state eq "OFF") {
-		$exit_code = 2;
-	}
-}
-else
-{
-	fail "fail: illegal action";
-}
-
-if ($success)
-{
-	print "success: domain $domain $action". ((defined $state) ? ": $state":"")
-		."\n" unless defined $quiet;
-	exit $exit_code;
-}
-else
-{
-	fail "fail: domain $domain $action";	
-	exit 1
-}
-
-
diff --git a/fence/agents/cisco_mds/Makefile.am b/fence/agents/cisco_mds/Makefile.am
index 3d262f6..c6a19de 100644
--- a/fence/agents/cisco_mds/Makefile.am
+++ b/fence/agents/cisco_mds/Makefile.am
@@ -10,8 +10,8 @@ sbin_SCRIPTS		= $(TARGET)
 
 man_MANS		= $(TARGET).8
 
+FENCE_TEST_ARGS         = -l test -p test -a test -n fc1/1
+
 include $(top_srcdir)/make/fencebuild.mk
 include $(top_srcdir)/make/fenceman.mk
-
-clean-local: clean-man
-	rm -f $(TARGET)
+include $(top_srcdir)/make/agentpycheck.mk
diff --git a/fence/agents/cisco_mds/fence_cisco_mds.py b/fence/agents/cisco_mds/fence_cisco_mds.py
index 4acce4f..ba9d917 100644
--- a/fence/agents/cisco_mds/fence_cisco_mds.py
+++ b/fence/agents/cisco_mds/fence_cisco_mds.py
@@ -1,4 +1,4 @@
-#!/usr/bin/python
+#!/usr/bin/python -tt
 
 # The Following agent has been tested on:
 # - Cisco MDS UROS 9134 FC (1 Slot) Chassis ("1/2/4 10 Gbps FC/Supervisor-2") Motorola, e500v2
@@ -7,9 +7,11 @@
 #   with BIOS 1.0.16, kickstart 4.1(1c), system 4.1(1c)
 
 import sys, re
+import atexit
 sys.path.append("@FENCEAGENTSLIBDIR@")
 from fencing import *
-from fencing_snmp import *
+from fencing import fail_usage, array_to_dict
+from fencing_snmp import FencingSnmp
 
 #BEGIN_VERSION_GENERATION
 RELEASE_VERSION="Cisco MDS 9xxx SNMP fence agent"
@@ -35,24 +37,19 @@ PORT_OID = ""
 def cisco_port2oid(port):
 	port = port.lower()
 
-	nums = re.match('^fc(\d+)/(\d+)$', port)
+	nums = re.match(r'^fc(\d+)/(\d+)$', port)
 
-	if ((nums) and (len(nums.groups()))==2):
+	if nums and len(nums.groups()) == 2:
 		return "%s.%d.%d"% (PORT_ADMIN_STATUS_OID, int(nums.group(1))+21, int(nums.group(2))-1)
 	else:
 		fail_usage("Mangled port number: %s"%(port))
 
 def get_power_status(conn, options):
-	(oid, status) = conn.get(PORT_OID)
-	return (status=="1" and "on" or "off")
+	(_, status) = conn.get(PORT_OID)
+	return status == "1" and "on" or "off"
 
 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(map(lambda y:[y[0].split('.')[-1], y[1]], ar))
+	conn.set(PORT_OID, (options["--action"] == "on" and 1 or 2))
 
 def get_outlets_status(conn, options):
 	result = {}
@@ -60,7 +57,7 @@ def get_outlets_status(conn, options):
 	res_fc = conn.walk(PORTS_OID, 30)
 	res_aliases = array_to_dict(conn.walk(ALIASES_OID, 30))
 
-	fc_re = re.compile('^"fc\d+/\d+"$')
+	fc_re = re.compile(r'^"fc\d+/\d+"$')
 
 	for x in res_fc:
 		if fc_re.match(x[1]):
@@ -77,28 +74,26 @@ def get_outlets_status(conn, options):
 def main():
 	global PORT_OID
 
-	device_opt = [ "fabric_fencing", "ipaddr", "login", "passwd", "no_login", "no_password", \
-		       "port", "snmp_version", "community" ]
+	device_opt = ["fabric_fencing", "ipaddr", "login", "passwd", "no_login", "no_password", \
+		       "port", "snmp_version", "snmp"]
 
 	atexit.register(atexit_handler)
 
-	snmp_define_defaults ()
-
 	options = check_input(device_opt, process_input(device_opt))
 
-	docs = { }           
+	docs = {}
 	docs["shortdesc"] = "Fence agent for Cisco MDS"
 	docs["longdesc"] = "fence_cisco_mds is an I/O Fencing agent \
 which can be used with any Cisco MDS 9000 series with SNMP enabled device."
 	docs["vendorurl"] = "http://www.cisco.com"
 	show_docs(options, docs)
 
-	if (not (options["--action"] in ["list","monitor"])):
+	if not options["--action"] in ["list", "monitor"]:
 		PORT_OID = cisco_port2oid(options["--plug"])
 
 	# Operate the fencing device
 	result = fence_action(FencingSnmp(options), options, set_power_status, get_power_status, get_outlets_status)
-	
+
 	sys.exit(result)
 
 if __name__ == "__main__":
diff --git a/fence/agents/cisco_ucs/Makefile.am b/fence/agents/cisco_ucs/Makefile.am
index c12e5ef..cc81ee6 100644
--- a/fence/agents/cisco_ucs/Makefile.am
+++ b/fence/agents/cisco_ucs/Makefile.am
@@ -10,8 +10,8 @@ sbin_SCRIPTS		= $(TARGET)
 
 man_MANS		= $(TARGET).8
 
+FENCE_TEST_ARGS         = -l test -p test -a test -n 1
+
 include $(top_srcdir)/make/fencebuild.mk
 include $(top_srcdir)/make/fenceman.mk
-
-clean-local: clean-man
-	rm -f $(TARGET)
+include $(top_srcdir)/make/agentpycheck.mk
diff --git a/fence/agents/cisco_ucs/fence_cisco_ucs.py b/fence/agents/cisco_ucs/fence_cisco_ucs.py
index f70a835..6288207 100644
--- a/fence/agents/cisco_ucs/fence_cisco_ucs.py
+++ b/fence/agents/cisco_ucs/fence_cisco_ucs.py
@@ -1,9 +1,12 @@
-#!/usr/bin/python
+#!/usr/bin/python -tt
 
 import sys, re
 import pycurl, StringIO
+import logging
+import atexit
 sys.path.append("@FENCEAGENTSLIBDIR@")
 from fencing import *
+from fencing import fail, EC_STATUS, EC_LOGIN_DENIED, run_delay
 
 #BEGIN_VERSION_GENERATION
 RELEASE_VERSION="New Cisco UCS Agent - test release on steroids"
@@ -16,61 +19,65 @@ RE_STATUS = re.compile("<lsPower .*? state=\"(.*?)\"", re.IGNORECASE)
 RE_GET_DN = re.compile(" dn=\"(.*?)\"", re.IGNORECASE)
 RE_GET_DESC = re.compile(" descr=\"(.*?)\"", re.IGNORECASE)
 
+options_global = None
+
 def get_power_status(conn, options):
-	res = send_command(options, \
-		"<configResolveDn cookie=\"" + options["cookie"] + "\" inHierarchical=\"false\" dn=\"org-root" + options["--suborg"] + \
-		"/ls-" + options["--plug"] + "/power\"/>", \
-		 int(options["--shell-timeout"]))
+	del conn
+
+	res = send_command(options, "<configResolveDn cookie=\"" + options["cookie"] +
+			"\" inHierarchical=\"false\" dn=\"org-root" + options["--suborg"] + "/ls-" +
+			options["--plug"] + "/power\"/>", int(options["--shell-timeout"]))
 
 	result = RE_STATUS.search(res)
-	if (result == None):
+	if result == None:
 		fail(EC_STATUS)
 	else:
 		status = result.group(1)
 
-	if (status == "up"):
+	if status == "up":
 		return "on"
 	else:
 		return "off"
 
 def set_power_status(conn, options):
+	del conn
+
 	action = {
 		'on' : "up",
 		'off' : "down"
 	}[options["--action"]]
-	
-	res = send_command(options, \
-		"<configConfMos cookie=\"" + options["cookie"] + "\" inHierarchical=\"no\">" + \
-		"<inConfigs><pair key=\"org-root" + options["--suborg"] + "/ls-" + options["--plug"] + "/power\">" + \
-		"<lsPower dn=\"org-root/ls-" + options["--plug"] + "/power\" state=\"" + action + "\" status=\"modified\" />" + \
-		"</pair></inConfigs></configConfMos>", \
-		int(options["--shell-timeout"]))
-	
+
+	send_command(options, "<configConfMos cookie=\"" + options["cookie"] + "\" inHierarchical=\"no\">" +
+			"<inConfigs><pair key=\"org-root" + options["--suborg"] + "/ls-" + options["--plug"] +
+			"/power\">" + "<lsPower dn=\"org-root/ls-" + options["--plug"] + "/power\" state=\"" +
+			action + "\" status=\"modified\" />" + "</pair></inConfigs></configConfMos>",
+			int(options["--shell-timeout"]))
+
 	return
 
 def get_list(conn, options):
-	outlets = { }
+	del conn
+	outlets = {}
 
 	try:
-		res = send_command(options, \
-			"<configResolveClass cookie=\"" + options["cookie"] + "\" inHierarchical=\"false\" classId=\"lsServer\"/>", \
-			int(options["--shell-timeout"]))
+		res = send_command(options, "<configResolveClass cookie=\"" + options["cookie"] +
+				"\" inHierarchical=\"false\" classId=\"lsServer\"/>", int(options["--shell-timeout"]))
 
 		lines = res.split("<lsServer ")
 		for i in range(1, len(lines)):
-			dn = RE_GET_DN.search(lines[i]).group(1)
+			node_name = RE_GET_DN.search(lines[i]).group(1)
 			desc = RE_GET_DESC.search(lines[i]).group(1)
-			outlets[dn] = (desc, None)
+			outlets[node_name] = (desc, None)
 	except AttributeError:
-		return { }
+		return {}
 	except IndexError:
-		return { }
+		return {}
 
 	return outlets
 
 def send_command(opt, command, timeout):
 	## setup correct URL
-	if opt.has_key("--ssl"):
+	if "--ssl" in opt or "--ssl-secure" in opt or "--ssl-insecure" in opt:
 		url = "https:"
 	else:
 		url = "http:"
@@ -78,80 +85,89 @@ def send_command(opt, command, timeout):
 	url += "//" + opt["--ip"] + ":" + str(opt["--ipport"]) + "/nuova"
 
 	## send command through pycurl
-	c = pycurl.Curl()
-	b = StringIO.StringIO()
-	c.setopt(pycurl.URL, url)
-	c.setopt(pycurl.HTTPHEADER, [ "Content-type: text/xml" ])
-	c.setopt(pycurl.POSTFIELDS, command)
-	c.setopt(pycurl.WRITEFUNCTION, b.write)
-	c.setopt(pycurl.TIMEOUT, timeout)
-	c.setopt(pycurl.SSL_VERIFYPEER, 0)
-	c.setopt(pycurl.SSL_VERIFYHOST, 0)
-	c.perform()
-	result = b.getvalue()
-
-	if opt["log"] >= LOG_MODE_VERBOSE:
-		opt["debug_fh"].write(command + "\n")
-		opt["debug_fh"].write(result + "\n")
+	conn = pycurl.Curl()
+	web_buffer = StringIO.StringIO()
+	conn.setopt(pycurl.URL, url)
+	conn.setopt(pycurl.HTTPHEADER, ["Content-type: text/xml"])
+	conn.setopt(pycurl.POSTFIELDS, command)
+	conn.setopt(pycurl.WRITEFUNCTION, web_buffer.write)
+	conn.setopt(pycurl.TIMEOUT, timeout)
+	if opt.has_key("--ssl") or opt.has_key("--ssl-secure"):
+		conn.setopt(pycurl.SSL_VERIFYPEER, 1)
+		conn.setopt(pycurl.SSL_VERIFYHOST, 2)
+
+	if opt.has_key("--ssl-insecure"):
+		conn.setopt(pycurl.SSL_VERIFYPEER, 0)
+		conn.setopt(pycurl.SSL_VERIFYHOST, 0)
+	conn.perform()
+	result = web_buffer.getvalue()
+
+	logging.debug("%s\n", command)
+	logging.debug("%s\n", result)
 
 	return result
 
 def define_new_opts():
 	all_opt["suborg"] = {
-		"getopt" : "s:",
+		"getopt" : ":",
 		"longopt" : "suborg",
 		"help" : "--suborg=[path]                Additional path needed to access suborganization",
 		"required" : "0",
 		"shortdesc" : "Additional path needed to access suborganization",
 		"default" : "",
-		"order" : 1 }
+		"order" : 1}
+
+def logout():
+	### Logout; we do not care about result as we will end in any case
+	try:
+		send_command(options_global, "<aaaLogout inCookie=\"" + options_global["cookie"] + "\" />",
+				int(options_global["--shell-timeout"]))
+	except Exception:
+		pass
 
 def main():
-	device_opt = [ "ipaddr", "login", "passwd", "ssl", "port", "web", "suborg" ]
+	global options_global
+	device_opt = ["ipaddr", "login", "passwd", "ssl", "notls", "port", "web", "suborg"]
 
 	atexit.register(atexit_handler)
+	atexit.register(logout)
 
 	define_new_opts()
-	
-	options = check_input(device_opt, process_input(device_opt))
 
-	docs = { }
+	options_global = check_input(device_opt, process_input(device_opt))
+
+	docs = {}
 	docs["shortdesc"] = "Fence agent for Cisco UCS"
 	docs["longdesc"] = "fence_cisco_ucs is an I/O Fencing agent which can be \
 used with Cisco UCS to fence machines."
 	docs["vendorurl"] = "http://www.cisco.com"
-	show_docs(options, docs)
-
-	## Do the delay of the fence device before logging in
-	## Delay is important for two-node clusters fencing but we do not need to delay 'status' operations
-	if options["--action"] in ["off", "reboot"]:
-		time.sleep(int(options["--delay"]))
+	show_docs(options_global, docs)
 
+	run_delay(options_global)
 	### Login
 	try:
-		res = send_command(options, "<aaaLogin inName=\"" + options["--username"] + "\" inPassword=\"" + options["--password"] + "\" />", int(options["--login-timeout"]))
+		res = send_command(options_global, "<aaaLogin inName=\"" + options_global["--username"] +
+				"\" inPassword=\"" + options_global["--password"] + "\" />", int(options_global["--login-timeout"]))
 		result = RE_COOKIE.search(res)
-		if (result == None):	
+		if result == None:
 			## Cookie is absenting in response
 			fail(EC_LOGIN_DENIED)
-	except:
+	except Exception:
 		fail(EC_LOGIN_DENIED)
 
-	options["cookie"] = result.group(1)
+	options_global["cookie"] = result.group(1)
 
 	##
 	## Modify suborg to format /suborg
-	if options["--suborg"] != "":
-		options["--suborg"] = "/" + options["--suborg"].lstrip("/").rstrip("/")
+	if options_global["--suborg"] != "":
+		options_global["--suborg"] = "/" + options_global["--suborg"].lstrip("/").rstrip("/")
 
 	##
 	## Fence operations
 	####
-	result = fence_action(None, options, set_power_status, get_power_status, get_list)
+	result = fence_action(None, options_global, set_power_status, get_power_status, get_list)
 
-	### Logout; we do not care about result as we will end in any case
-	send_command(options, "<aaaLogout inCookie=\"" + options["cookie"] + "\" />", int(options["--shell-timeout"]))
-	
+	## Logout is done every time at atexit phase
 	sys.exit(result)
 
 if __name__ == "__main__":
diff --git a/fence/agents/cpint/Makefile.am b/fence/agents/cpint/Makefile.am
deleted file mode 100644
index c9680bd..0000000
--- a/fence/agents/cpint/Makefile.am
+++ /dev/null
@@ -1,17 +0,0 @@
-MAINTAINERCLEANFILES	= Makefile.in
-
-TARGET			= fence_cpint
-
-SRC			= $(TARGET).pl
-
-EXTRA_DIST		= $(SRC)
-
-sbin_SCRIPTS		= $(TARGET)
-
-man_MANS		= $(TARGET).8
-
-include $(top_srcdir)/make/fencebuild.mk
-include $(top_srcdir)/make/fencemanperl.mk
-
-clean-local: clean-man
-	rm -f $(TARGET)
diff --git a/fence/agents/cpint/fence_cpint.pl b/fence/agents/cpint/fence_cpint.pl
deleted file mode 100644
index 7a7a5f5..0000000
--- a/fence/agents/cpint/fence_cpint.pl
+++ /dev/null
@@ -1,188 +0,0 @@
-#!/usr/bin/perl
-
-use Getopt::Std;
-
-my $ME = $0;
-
-END {
-  defined fileno STDOUT or return;
-  close STDOUT and return;
-  warn "$ME: failed to close standard output: $!\n";
-  $? ||= 1;
-}
-
-# Get the program name from $0 and strip directory names
-$_=$0;
-s/.*\///;
-my $pname = $_;
-
-$comm_prog = "hcp";
-
-# WARNING!! Do not add code bewteen "#BEGIN_VERSION_GENERATION" and
-# "#END_VERSION_GENERATION"  It is generated by the Makefile
-
-#BEGIN_VERSION_GENERATION
-$RELEASE_VERSION="";
-$REDHAT_COPYRIGHT="";
-$BUILD_DATE="";
-#END_VERSION_GENERATION
-
-
-sub usage
-{
-    print "Usage:\n";  
-    print "\n";
-    print "$pname [options]\n";
-    print "\n";
-    print "Options:\n";
-    print "  -h               usage\n";
-    print "  -o metadata      print XML metadata for fence agent\n";
-    print "  -u <string>      userid of the virtual machine to fence\n";
-    print "  -q               quiet mode\n";
-    print "  -V               Version\n";
-
-    exit 0;
-}
-
-sub fail
-{
-  ($msg)=@_;
-  print "failed: " . $msg . "\n" unless defined $opt_q;
-  exit 1;
-}
-
-sub fail_usage
-{
-  ($msg)=@_q;
-  print stderr $msg."\n" if $msg;
-  print stderr "Please use '-h' for usage.\n";
-  exit 1;
-}
-
-sub version
-{
-  print "$pname $RELEASE_VERSION $BUILD_DATE\n";
-  print "$REDHAT_COPYRIGHT\n" if ( $REDHAT_COPYRIGHT );
-
-  exit 0;
-}
-
-sub print_metadata
-{
-print '<?xml version="1.0" ?>
-<resource-agent name="fence_cpint" shortdesc="I/O Fencing agent for GFS on s390 and zSeries VM clusters" >
-<longdesc>
-fence_cpint is an I/O Fencing agent used on a virtual machine running GFS in a s390 or zSeries VM cluster. It uses the cpint package to send a CP LOGOFF command to the specified virtual machine. For fence_cpint to execute correctly, you must have the cpint module installed, and hcp in your PATH.
-
-NOTE: for fence_cpint to send a command to another virtual machine, the machine executing it must either be a privilege class C user or it must be the secondary user of the virtual machine to be fenced. This means that unless all of you GULM server nodes are privilege class C, fence_cpint can only be used with SLM.
-</longdesc>
-<vendor-url>http://www.ibm.com</vendor-url>
-<parameters>
-        <parameter name="userid" unique="1" required="1">
-                <getopt mixed="-u [userid]" />
-                <content type="string"  />
-                <shortdesc lang="en">Userid of the virtual machine to fence</shortdesc>
-        </parameter>
-        <parameter name="help" unique="1" required="0">
-                <getopt mixed="-h" />           
-                <content type="string"  />
-                <shortdesc lang="en">Display help and exit</shortdesc>                    
-        </parameter>
-</parameters>
-<actions>
-        <action name="metadata" />
-</actions>
-</resource-agent>
-';
-}
-
-sub get_options_stdin
-{
-    my $opt;
-    my $line = 0;
-    while( defined($in = <>) )
-    {
-        $_ = $in;
-	      chomp;
-
-        # strip leading and trailing whitespace
-        s/^\s*//;
-        s/\s*$//;
-
-        # skip comments
-        next if /^#/;
-
-	      $line+=1;
-        $opt=$_;
-        next unless $opt;
-
-	      ($name,$val)=split /\s*=\s*/, $opt;
-
-	      if ( $name eq "" )
-        {
-           print stderr "parse error: illegal name in option $line\n";
-           exit 2;
-        }
-
-	      # DO NOTHING -- this field is used by fenced or stomithd
-        elsif ($name eq "agent" ) { }
-
-	      # FIXME -- depricated.  use "userid" and "password" instead.
-        elsif ($name eq "fm" )
-        {
-            (my $dummy,$opt_u,$opt_p) = split /\s+/,$val;
-	          print STDERR "Depricated \"fm\" entry detected.  refer to man page.\n";
-        }
-
-        # FIXME -- depreicated residue of old fencing system
-      	elsif ($name eq "name" ) { }
-
-	      elsif ($name eq "userid" )
-        {
-            $opt_u = $val;
-        }
-
-        elsif ($name eq "action" )
-        {
-            $opt_o = $val;
-        }
-
-	else
-        {
-           print stderr "parse error: unknown option \"$opt\"\n";
-           #> exit 2;
-        }
-    }
-}
-
-if (@ARGV > 0){
-    getopts("hqu:Vo:") || fail_usage;
-    usage if defined $opt_h;
-    version if defined $opt_V;
-
-    fail_usage "Unkown parameter." if (@ARGV > 0);
-
-    if ((defined $opt_o) && ($opt_o =~ /metadata/i)) {
-        print_metadata();
-        exit 0;
-    }
-
-    fail_usage "No '-u' flag specified." unless defined $opt_u;
-} else {
-    get_options_stdin();
-
-    if ((defined $opt_o) && ($opt_o =~ /metadata/i)) {
-        print_metadata();
-        exit 0;
-    }
-
-    fail "no userid" unless defined $opt_u;
-}
-
-$ret_val = system("$comm_prog send cp $opt_u logoff > /dev/null 2>&1") >> 8;
-fail "$comm_prog failed ($ret_val)" unless ($ret_val == 0 || $ret_val == 45);
-$ret_val = system("$comm_prog send cp $opt_u > /dev/null 2>&1") >> 8;
-fail "$userid isn't logged off. $comm_prog return ($ret_val)" unless ($ret_val == 45);
-
-print "success: booted userid $opt_u\n" unless defined $opt_q;
-exit 0;
diff --git a/fence/agents/apc/Makefile.am b/fence/agents/docker/Makefile.am
similarity index 68%
copy from fence/agents/apc/Makefile.am
copy to fence/agents/docker/Makefile.am
index 355c873..5e623f7 100644
--- a/fence/agents/apc/Makefile.am
+++ b/fence/agents/docker/Makefile.am
@@ -1,6 +1,6 @@
 MAINTAINERCLEANFILES	= Makefile.in
 
-TARGET			= fence_apc
+TARGET			= fence_docker
 
 SRC			= $(TARGET).py
 
@@ -10,8 +10,8 @@ sbin_SCRIPTS		= $(TARGET)
 
 man_MANS		= $(TARGET).8
 
+FENCE_TEST_ARGS		= -a test -n 1
+
 include $(top_srcdir)/make/fencebuild.mk
 include $(top_srcdir)/make/fenceman.mk
-
-clean-local: clean-man
-	rm -f $(TARGET)
+include $(top_srcdir)/make/agentpycheck.mk
diff --git a/fence/agents/docker/fence_docker.py b/fence/agents/docker/fence_docker.py
new file mode 100644
index 0000000..7363611
--- /dev/null
+++ b/fence/agents/docker/fence_docker.py
@@ -0,0 +1,152 @@
+#!/usr/bin/python -tt
+
+import atexit
+import sys
+import StringIO
+import logging
+import pycurl
+import json
+
+sys.path.append("@FENCEAGENTSLIBDIR@")
+from fencing import fail_usage, all_opt, fence_action, atexit_handler, check_input, process_input, show_docs, run_delay
+
+#BEGIN_VERSION_GENERATION
+RELEASE_VERSION = ""
+REDHAT_COPYRIGHT = ""
+BUILD_DATE = ""
+#END_VERSION_GENERATION
+
+def get_power_status(conn, options):
+	del conn
+	status = send_cmd(options, "containers/%s/json" % options["--plug"])
+	if status is None:
+		return None
+	return "on" if status["State"]["Running"] else "off"
+
+
+def set_power_status(conn, options):
+	del conn
+	if options["--action"] == "on":
+		send_cmd(options, "containers/%s/start" % options["--plug"], True)
+	else:
+		send_cmd(options, "containers/%s/kill" % options["--plug"], True)
+	return
+
+
+def reboot_cycle(conn, options):
+	del conn
+	send_cmd(options, "containers/%s/restart" % options["--plug"], True)
+	return get_power_status(conn, options)
+
+
+def get_list(conn, options):
+	del conn
+	output = send_cmd(options, "containers/json?all=1")
+	containers = {}
+	for container in output:
+		containers[container["Id"]] = (container["Names"][0], {True:"off", False: "on"}[container["Status"][:4].lower() == "exit"])
+	return containers
+
+
+def send_cmd(options, cmd, post = False):
+	url = "http%s://%s:%s/v1.11/%s" % ("s" if "--ssl" in options else "", options["--ip"], options["--ipport"], 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 post:
+		conn.setopt(pycurl.POST, 1)
+		conn.setopt(pycurl.POSTFIELDSIZE, 0)
+	conn.setopt(pycurl.WRITEFUNCTION, output_buffer.write)
+	conn.setopt(pycurl.TIMEOUT, int(options["--shell-timeout"]))
+	if "--ssl" in options:
+		if not (set(("--tlscert", "--tlskey", "--tlscacert")) <= set(options)):
+			fail_usage("Failed. If --ssl option is used, You have to also \
+specify: --tlscert, --tlskey and --tlscacert")
+		conn.setopt(pycurl.SSL_VERIFYPEER, 1)
+		conn.setopt(pycurl.SSLCERT, options["--tlscert"])
+		conn.setopt(pycurl.SSLKEY, options["--tlskey"])
+		conn.setopt(pycurl.CAINFO, options["--tlscacert"])
+	else:
+		conn.setopt(pycurl.SSL_VERIFYPEER, 0)
+		conn.setopt(pycurl.SSL_VERIFYHOST, 0)
+
+	logging.debug("URL: " + url)
+
+	try:
+		conn.perform()
+		result = output_buffer.getvalue()
+		return_code = conn.getinfo(pycurl.RESPONSE_CODE)
+
+		logging.debug("RESULT [" + str(return_code) + \
+			"]: " + result)
+		conn.close()
+		if return_code == 200:
+			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["tlscert"] = {
+		"getopt" : ":",
+		"longopt" : "tlscert",
+		"help" : "--tlscert                      "
+			"Path to client certificate for TLS authentication",
+		"required" : "0",
+		"shortdesc" : "Path to client certificate (PEM format) \
+for TLS authentication. Required if --ssl option is used.",
+		"order": 2
+	}
+
+	all_opt["tlskey"] = {
+		"getopt" : ":",
+		"longopt" : "tlskey",
+		"help" : "--tlskey                       "
+			"Path to client key for TLS authentication",
+		"required" : "0",
+		"shortdesc" : "Path to client key (PEM format) for TLS \
+authentication.  Required if --ssl option is used.",
+		"order": 2
+	}
+
+	all_opt["tlscacert"] = {
+		"getopt" : ":",
+		"longopt" : "tlscacert",
+		"help" : "--tlscacert                    "
+			"Path to CA certificate for TLS authentication",
+		"required" : "0",
+		"shortdesc" : "Path to CA certificate (PEM format) for \
+TLS authentication.  Required if --ssl option is used.",
+		"order": 2
+	}
+
+	device_opt = ["ipaddr", "no_password", "no_login", "port", "method", "web", "tlscert", "tlskey", "tlscacert", "ssl"]
+
+	options = check_input(device_opt, process_input(device_opt))
+
+	docs = { }
+	docs["shortdesc"] = "Fence agent for Docker"
+	docs["longdesc"] = "fence_docker is I/O fencing agent which \
+can be used with the Docker Engine containers. You can use this \
+fence-agent without any authentication, or you can use TLS authentication \
+(use --ssl option, more info about TLS authentication in docker: \
+http://docs.docker.com/examples/https/)."
+	docs["vendorurl"] = "www.docker.io"
+	show_docs(options, docs)
+
+	run_delay(options)
+
+	result = fence_action(None, options, set_power_status, get_power_status, get_list, reboot_cycle)
+
+	sys.exit(result)
+
+if __name__ == "__main__":
+	main()
diff --git a/fence/agents/drac/Makefile.am b/fence/agents/drac/Makefile.am
index 0616c57..178da39 100644
--- a/fence/agents/drac/Makefile.am
+++ b/fence/agents/drac/Makefile.am
@@ -10,8 +10,8 @@ sbin_SCRIPTS		= $(TARGET)
 
 man_MANS		= $(TARGET).8
 
+FENCE_TEST_ARGS         = -l test -p test -a test
+
 include $(top_srcdir)/make/fencebuild.mk
 include $(top_srcdir)/make/fenceman.mk
-
-clean-local: clean-man
-	rm -f $(TARGET)
+include $(top_srcdir)/make/agentpycheck.mk
diff --git a/fence/agents/drac/fence_drac.py b/fence/agents/drac/fence_drac.py
index c690b21..2bac539 100644
--- a/fence/agents/drac/fence_drac.py
+++ b/fence/agents/drac/fence_drac.py
@@ -1,6 +1,7 @@
-#!/usr/bin/python
+#!/usr/bin/python -tt
 
-import sys, re, pexpect, exceptions
+import sys, re
+import atexit
 sys.path.append("@FENCEAGENTSLIBDIR@")
 from fencing import *
 
@@ -12,9 +13,9 @@ BUILD_DATE=""
 
 def get_power_status(conn, options):
 	conn.send_eol("getmodinfo")
-	conn.log_expect(options, options["--command-prompt"], int(options["--shell-timeout"]))
-	status = re.compile("\s+(on|off)\s+", re.IGNORECASE).search(conn.before).group(1)
-	return (status.lower().strip())
+	conn.log_expect(options["--command-prompt"], int(options["--shell-timeout"]))
+	status = re.compile(r"\s+(on|off)\s+", re.IGNORECASE).search(conn.before).group(1)
+	return status.lower().strip()
 
 def set_power_status(conn, options):
 	action = {
@@ -23,22 +24,22 @@ def set_power_status(conn, options):
 	}[options["--action"]]
 
 	conn.send_eol("serveraction -d 0 " + action)
-	conn.log_expect(options, options["--command-prompt"], int(options["--shell-timeout"]))
+	conn.log_expect(options["--command-prompt"], int(options["--shell-timeout"]))
 
 def main():
-	device_opt = [ "ipaddr", "login", "passwd", "cmd_prompt" ]
+	device_opt = ["ipaddr", "login", "passwd", "cmd_prompt", "telnet"]
 
 	atexit.register(atexit_handler)
 
 	opt = process_input(device_opt)
 	if "--username" in opt:
-		all_opt["cmd_prompt"]["default"] = [ "\\[" + opt["--username"] + "\\]# " ]
+		all_opt["cmd_prompt"]["default"] = ["\\[" + opt["--username"] + "\\]# "]
 	else:
-		all_opt["cmd_prompt"]["default"] = [ "\\[" "username" + "\\]# " ]
-	
+		all_opt["cmd_prompt"]["default"] = ["\\[" "username" + "\\]# "]
+
 	options = check_input(device_opt, opt)
 
-	docs = { }
+	docs = {}
 	docs["shortdesc"] = "I/O Fencing agent for Dell DRAC IV"
 	docs["longdesc"] = "fence_drac is an I/O Fencing agent which can be used with \
 the Dell Remote Access Card (DRAC). This card provides remote access to controlling \
@@ -60,20 +61,7 @@ To enable telnet on the DRAC: \
 	####
 	conn = fence_login(options)
 	result = fence_action(conn, options, set_power_status, get_power_status, None)
-
-	##
-	## Logout from system
-	##
-	## In some special unspecified cases it is possible that 
-	## connection will be closed before we run close(). This is not 
-	## a problem because everything is checked before.
-	######
-	try:
-		conn.send_eol("exit")
-		conn.close()
-	except:
-		pass
-	
+	fence_logout(conn, "exit")
 	sys.exit(result)
 
 if __name__ == "__main__":
diff --git a/fence/agents/drac5/Makefile.am b/fence/agents/drac5/Makefile.am
index 2654360..8324764 100644
--- a/fence/agents/drac5/Makefile.am
+++ b/fence/agents/drac5/Makefile.am
@@ -10,8 +10,8 @@ sbin_SCRIPTS		= $(TARGET)
 
 man_MANS		= $(TARGET).8
 
+FENCE_TEST_ARGS         = -l test -p test -a test -n 1
+
 include $(top_srcdir)/make/fencebuild.mk
 include $(top_srcdir)/make/fenceman.mk
-
-clean-local: clean-man
-	rm -f $(TARGET)
+include $(top_srcdir)/make/agentpycheck.mk
diff --git a/fence/agents/drac5/fence_drac5.py b/fence/agents/drac5/fence_drac5.py
index 2c067a7..070fe41 100644
--- a/fence/agents/drac5/fence_drac5.py
+++ b/fence/agents/drac5/fence_drac5.py
@@ -1,4 +1,4 @@
-#!/usr/bin/python
+#!/usr/bin/python -tt
 
 #####
 ##
@@ -12,9 +12,11 @@
 ## @note: drac_version was removed
 #####
 
-import sys, re, pexpect, exceptions, time
+import sys, re, time
+import atexit
 sys.path.append("@FENCEAGENTSLIBDIR@")
 from fencing import *
+from fencing import fail_usage
 
 #BEGIN_VERSION_GENERATION
 RELEASE_VERSION="New Drac5 Agent - test release on steroids"
@@ -24,16 +26,17 @@ BUILD_DATE="March, 2008"
 
 def get_power_status(conn, options):
 	if options["--drac-version"] == "DRAC MC":
-		(_, status) = get_list_devices(conn,options)[options["--plug"]]
+		(_, status) = get_list_devices(conn, options)[options["--plug"]]
 	else:
 		if options["--drac-version"] == "DRAC CMC":
 			conn.send_eol("racadm serveraction powerstatus -m " + options["--plug"])
 		elif options["--drac-version"] == "DRAC 5":
 			conn.send_eol("racadm serveraction powerstatus")
-		
-		conn.log_expect(options, options["--command-prompt"], int(options["--shell-timeout"]))
-				
-		status = re.compile("(^|: )(ON|OFF|Powering ON|Powering OFF)\s*$", re.IGNORECASE | re.MULTILINE).search(conn.before).group(2)
+
+		conn.log_expect(options["--command-prompt"], int(options["--shell-timeout"]))
+
+		status = re.compile(r"(^|: )(ON|OFF|Powering ON|Powering OFF)\s*$",
+				re.IGNORECASE | re.MULTILINE).search(conn.before).group(2)
 
 	if status.lower().strip() in ["on", "powering on", "powering off"]:
 		return "on"
@@ -55,30 +58,30 @@ def set_power_status(conn, options):
 
 	## Fix issue with double-enter [CR/LF]
 	##	We need to read two additional command prompts (one from get + one from set command)
-	conn.log_expect(options, options["--command-prompt"], int(options["--power-timeout"]))
+	conn.log_expect(options["--command-prompt"], int(options["--power-timeout"]))
 	if len(conn.before.strip()) == 0:
 		options["eol"] = options["eol"][:-1]
-		conn.log_expect(options, options["--command-prompt"], int(options["--power-timeout"]))
-		conn.log_expect(options, options["--command-prompt"], int(options["--power-timeout"]))
+		conn.log_expect(options["--command-prompt"], int(options["--power-timeout"]))
+		conn.log_expect(options["--command-prompt"], int(options["--power-timeout"]))
 
 def get_list_devices(conn, options):
-	outlets = { }
+	outlets = {}
 
 	if options["--drac-version"] == "DRAC CMC":
 		conn.send_eol("getmodinfo")
 
-		list_re = re.compile("^([^\s]*?)\s+Present\s*(ON|OFF)\s*.*$")
-		conn.log_expect(options, options["--command-prompt"], int(options["--power-timeout"]))
+		list_re = re.compile(r"^([^\s]*?)\s+Present\s*(ON|OFF)\s*.*$")
+		conn.log_expect(options["--command-prompt"], int(options["--power-timeout"]))
 		for line in conn.before.splitlines():
-			if (list_re.search(line)):
+			if list_re.search(line):
 				outlets[list_re.search(line).group(1)] = ("", list_re.search(line).group(2))
 	elif options["--drac-version"] == "DRAC MC":
 		conn.send_eol("getmodinfo")
 
-		list_re = re.compile("^\s*([^\s]*)\s*---->\s*(.*?)\s+Present\s*(ON|OFF)\s*.*$")
-		conn.log_expect(options, options["--command-prompt"], int(options["--power-timeout"]))
+		list_re = re.compile(r"^\s*([^\s]*)\s*---->\s*(.*?)\s+Present\s*(ON|OFF)\s*.*$")
+		conn.log_expect(options["--command-prompt"], int(options["--power-timeout"]))
 		for line in conn.before.splitlines():
-			if (list_re.search(line)):
+			if list_re.search(line):
 				outlets[list_re.search(line).group(2)] = ("", list_re.search(line).group(3))
 	elif options["--drac-version"] == "DRAC 5":
 		## DRAC 5 can be used only for one computer
@@ -96,23 +99,23 @@ def define_new_opts():
 		"help" : "-d, --drac-version=[version]   Force DRAC version to use (DRAC 5, DRAC CMC, DRAC MC)",
 		"required" : "0",
 		"shortdesc" : "Force DRAC version to use (DRAC 5, DRAC CMC, DRAC MC)",
-		"choices" : [ "DRAC CMC", "DRAC MC", "DRAC 5" ],
-		"order" : 1 }
+		"choices" : ["DRAC CMC", "DRAC MC", "DRAC 5"],
+		"order" : 1}
 
 def main():
-	device_opt = [  "ipaddr", "login", "passwd", "cmd_prompt", "secure", \
-			"drac_version", "port", "no_port" ]
+	device_opt = ["ipaddr", "login", "passwd", "cmd_prompt", "secure", \
+			"drac_version", "port", "no_port", "telnet"]
 
 	atexit.register(atexit_handler)
 
 	define_new_opts()
 
-	all_opt["cmd_prompt"]["default"] = [ "\$", "DRAC\/MC:" ]
+	all_opt["cmd_prompt"]["default"] = [r"\$", r"DRAC\/MC:"]
 
 	options = check_input(device_opt, process_input(device_opt))
 
-	docs = { }           
-	docs["shortdesc"] = "Fence agent for Dell DRAC CMC/5" 
+	docs = {}
+	docs["shortdesc"] = "Fence agent for Dell DRAC CMC/5"
 	docs["longdesc"] = "fence_drac5 is an I/O Fencing agent \
 which can be used with the Dell Remote Access Card v5 or CMC (DRAC). \
 This device provides remote access to controlling  power to a server. \
@@ -126,10 +129,10 @@ 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"
+			options["--drac-version"] = "DRAC CMC"
 		elif conn.before.find("DRAC 5") >= 0:
 			options["--drac-version"] = "DRAC 5"
 		elif conn.after.find("DRAC/MC") >= 0:
@@ -139,21 +142,11 @@ 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"]):
 			fail_usage("Failed: You have to enter module name (-n)")
 
 	result = fence_action(conn, options, set_power_status, get_power_status, get_list_devices)
-
-	##
-	## Logout from system
-	######
-	try:
-		conn.send_eol("exit")
-		time.sleep(1)
-		conn.close()
-	except:
-		pass
-	
+	fence_logout(conn, "exit", 1)
 	sys.exit(result)
 
 if __name__ == "__main__":
diff --git a/fence/agents/dummy/Makefile.am b/fence/agents/dummy/Makefile.am
index 11405eb..0c160a5 100644
--- a/fence/agents/dummy/Makefile.am
+++ b/fence/agents/dummy/Makefile.am
@@ -12,6 +12,4 @@ man_MANS		= $(TARGET).8
 
 include $(top_srcdir)/make/fencebuild.mk
 include $(top_srcdir)/make/fenceman.mk
-
-clean-local: clean-man
-	rm -f $(TARGET)
+include $(top_srcdir)/make/agentpycheck.mk
diff --git a/fence/agents/dummy/fence_dummy.py b/fence/agents/dummy/fence_dummy.py
index d5bb748..7f95b8f 100644
--- a/fence/agents/dummy/fence_dummy.py
+++ b/fence/agents/dummy/fence_dummy.py
@@ -1,8 +1,12 @@
-#!/usr/bin/python
+#!/usr/bin/python -tt
 
-import sys, re, pexpect, exceptions, random
+import sys, random
+import logging
+import time
+import atexit
 sys.path.append("@FENCEAGENTSLIBDIR@")
 from fencing import *
+from fencing import fail_usage
 
 #BEGIN_VERSION_GENERATION
 RELEASE_VERSION="New Dummy Agent - test release on steroids"
@@ -10,12 +14,14 @@ REDHAT_COPYRIGHT=""
 BUILD_DATE=""
 #END_VERSION_GENERATION
 
-plug_status="on"
+plug_status = "on"
 
 def get_power_status_file(conn, options):
+	del conn
+
 	try:
 		status_file = open(options["--status-file"], 'r')
-	except:
+	except Exception:
 		return "off"
 
 	status = status_file.read()
@@ -24,7 +30,9 @@ def get_power_status_file(conn, options):
 	return status.lower()
 
 def set_power_status_file(conn, options):
-	if not (options["--action"] in [ "on", "off" ]):
+	del conn
+
+	if not (options["--action"] in ["on", "off"]):
 		return
 
 	status_file = open(options["--status-file"], 'w')
@@ -32,21 +40,24 @@ def set_power_status_file(conn, options):
 	status_file.close()
 
 def get_power_status_fail(conn, options):
-	outlets = get_outlets_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]
 
 def set_power_status_fail(conn, options):
 	global plug_status
+	del conn
 
 	plug_status = "unknown"
 	if options["--action"] == "on":
 		plug_status = "off"
 
 def get_outlets_fail(conn, options):
+	del conn
+
 	result = {}
 	global plug_status
 
@@ -55,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"]
@@ -67,12 +78,12 @@ def get_outlets_fail(conn, options):
 	return result
 
 def main():
-	device_opt = [ "no_password", "status_file", "random_sleep_range", "type", "port" ]
+	device_opt = ["no_password", "status_file", "random_sleep_range", "type", "port"]
 
 	atexit.register(atexit_handler)
 
 	all_opt["status_file"] = {
-		"getopt" : "s:",
+		"getopt" : ":",
 		"longopt" : "status-file",
 		"help":"--status-file=[file]           Name of file that holds current status",
 		"required" : "0",
@@ -82,7 +93,7 @@ def main():
 		}
 
 	all_opt["random_sleep_range"] = {
-		"getopt" : "r:",
+		"getopt" : ":",
 		"longopt" : "random_sleep_range",
 		"help":"--random_sleep_range=[seconds] Issue a sleep between 1 and [seconds]",
 		"required" : "0",
@@ -91,7 +102,7 @@ def main():
 		}
 
 	all_opt["type"] = {
-		"getopt" : "t:",
+		"getopt" : ":",
 		"longopt" : "type",
 		"help":"--type=[type]                  Possible types are: file and fail",
 		"required" : "0",
@@ -107,7 +118,7 @@ def main():
 
 	options = check_input(device_opt, process_input(device_opt))
 
-	docs = { }
+	docs = {}
 	docs["shortdesc"] = "Dummy fence agent"
 	docs["longdesc"] = "fence_dummy"
 	docs["vendorurl"] = "http://www.example.com"
@@ -117,14 +128,14 @@ def main():
 	if options.has_key("--random_sleep_range"):
 		val = int(options["--random_sleep_range"])
 		ran = random.randint(1, val)
-		sys.stderr.write("random sleep for %d seconds\n" % ran)
+		logging.info("Random sleep for %d seconds\n", ran)
 		time.sleep(ran)
 
 	if options["--type"] == "fail":
 		result = fence_action(None, options, set_power_status_fail, get_power_status_fail, get_outlets_fail)
 	else:
 		result = fence_action(None, options, set_power_status_file, get_power_status_file, None)
-		
+
 	sys.exit(result)
 
 if __name__ == "__main__":
diff --git a/fence/agents/eaton_snmp/Makefile.am b/fence/agents/eaton_snmp/Makefile.am
index 0390800..415c2b6 100644
--- a/fence/agents/eaton_snmp/Makefile.am
+++ b/fence/agents/eaton_snmp/Makefile.am
@@ -11,8 +11,8 @@ sbin_SCRIPTS		= $(TARGET)
 
 man_MANS		= $(TARGET).8
 
+FENCE_TEST_ARGS         = -l test -p test -a test -n 1
+
 include $(top_srcdir)/make/fencebuild.mk
 include $(top_srcdir)/make/fenceman.mk
-
-clean-local: clean-man
-	rm -f $(TARGET)
+include $(top_srcdir)/make/agentpycheck.mk
diff --git a/fence/agents/eaton_snmp/fence_eaton_snmp.py b/fence/agents/eaton_snmp/fence_eaton_snmp.py
index 462d541..812790d 100644
--- a/fence/agents/eaton_snmp/fence_eaton_snmp.py
+++ b/fence/agents/eaton_snmp/fence_eaton_snmp.py
@@ -1,4 +1,4 @@
-#!/usr/bin/python
+#!/usr/bin/python -tt
 
 # The Following agent has been tested on:
 # - Eaton ePDU Managed - SNMP v1
@@ -7,9 +7,12 @@
 #   EATON | Powerware ePDU model: Switched ePDU (IPV3600), firmware: 2.0.K
 
 import sys
+import atexit
+import logging
 sys.path.append("@FENCEAGENTSLIBDIR@")
 from fencing import *
-from fencing_snmp import *
+from fencing import fail_usage
+from fencing_snmp import FencingSnmp
 
 #BEGIN_VERSION_GENERATION
 RELEASE_VERSION="Eaton SNMP fence agent"
@@ -35,7 +38,7 @@ after_set = False
 
 # Classes describing Device params
 # Managed ePDU
-class EatonManagedePDU:
+class EatonManagedePDU(object):
 	status_oid =       '.1.3.6.1.4.1.534.6.6.6.1.2.2.1.3.%d'
 	control_oid =      '.1.3.6.1.4.1.534.6.6.6.1.2.2.1.3.%d'
 	outlet_table_oid = '.1.3.6.1.4.1.534.6.6.6.1.2.2.1.1'
@@ -50,7 +53,7 @@ class EatonManagedePDU:
 
 # Switched ePDU (Pulizzi 2)
 # NOTE: sysOID reports "20677.1", while data are actually at "20677.2"
-class EatonSwitchedePDU:
+class EatonSwitchedePDU(object):
 	status_oid =       '.1.3.6.1.4.1.20677.2.6.3.%d.0'
 	control_oid =      '.1.3.6.1.4.1.20677.2.6.2.%d.0'
 	outlet_table_oid = '.1.3.6.1.4.1.20677.2.6.3'
@@ -64,82 +67,82 @@ class EatonSwitchedePDU:
 	has_switches = False
 
 ### FUNCTIONS ###
-def eaton_set_device(conn, options):
+def eaton_set_device(conn):
 	global device
 
 	agents_dir = {'.1.3.6.1.4.1.534.6.6.6':EatonManagedePDU,
 				'.1.3.6.1.4.1.20677.1':EatonSwitchedePDU,
-				'.1.3.6.1.4.1.20677.2':EatonSwitchedePDU }
+				'.1.3.6.1.4.1.20677.2':EatonSwitchedePDU}
 
 	# First resolve type of Eaton
 	eaton_type = conn.walk(OID_SYS_OBJECT_ID)
 
-	if (not ((len(eaton_type)==1) and (agents_dir.has_key(eaton_type[0][1])))):
+	if not ((len(eaton_type) == 1) and (agents_dir.has_key(eaton_type[0][1]))):
 		eaton_type = [[None, None]]
 
 	device = agents_dir[eaton_type[0][1]]
 
-	conn.log_command("Trying %s"%(device.ident_str))
+	logging.debug("Trying %s"%(device.ident_str))
 
 def eaton_resolv_port_id(conn, options):
 	global port_id, switch_id
 
-	if (device==None):
-		eaton_set_device(conn, options)
+	if device == None:
+		eaton_set_device(conn)
 
 	# Restore the increment, that was removed in main for ePDU Managed
-	if (device.ident_str == "Eaton Switched ePDU"):
+	if device.ident_str == "Eaton Switched ePDU":
 		options["--plug"] = str(int(options["--plug"]) + 1)
 
 	# Now we resolv port_id/switch_id
-	if ((options["--plug"].isdigit()) and ((not device.has_switches) or (options["--switch"].isdigit()))):
+	if options["--plug"].isdigit() and ((not device.has_switches) or (options["--switch"].isdigit())):
 		port_id = int(options["--plug"])
 
-		if (device.has_switches):
+		if device.has_switches:
 			switch_id = int(options["--switch"])
 	else:
 		table = conn.walk(device.outlet_table_oid, 30)
 
 		for x in table:
-			if (x[1].strip('"')==options["--plug"]):
+			if x[1].strip('"') == options["--plug"]:
 				t = x[0].split('.')
-				if (device.has_switches):
+				if device.has_switches:
 					port_id = int(t[len(t)-1])
 					switch_id = int(t[len(t)-3])
 				else:
-					if (device.ident_str == "Eaton Switched ePDU"):
+					if device.ident_str == "Eaton Switched ePDU":
 						port_id = int(t[len(t)-3])
 					else:
 						port_id = int(t[len(t)-1])
 
-	if (port_id==None):
+	if port_id == None:
 		# Restore index offset, to provide a valid error output on Managed ePDU
-		if (device.ident_str != "Eaton Switched ePDU"):
+		if device.ident_str != "Eaton Switched ePDU":
 			options["--plug"] = str(int(options["--plug"]) + 1)
 		fail_usage("Can't find port with name %s!"%(options["--plug"]))
 
 def get_power_status(conn, options):
 	global port_id, after_set
 
-	if (port_id==None):
+	if port_id == None:
 		eaton_resolv_port_id(conn, options)
 
 	# Ajust OID for Switched ePDU when the get is after a set
-	if ((after_set == True) and (device.ident_str == "Eaton Switched ePDU")):
+	if after_set and device.ident_str == "Eaton Switched ePDU":
 		port_id -= 1
 		after_set = False
 
 	oid = ((device.has_switches) and device.status_oid%(switch_id, port_id) or device.status_oid%(port_id))
 
 	try:
-		(oid, status)=conn.get(oid)
-		if (status==str(device.state_on)):
+		(oid, status) = conn.get(oid)
+		if status == str(device.state_on):
 			return "on"
-		elif (status==str(device.state_off)):
+		elif status == str(device.state_off):
 			return "off"
 		else:
 			return None
-	except:
+	except Exception:
 		return None
 
 def set_power_status(conn, options):
@@ -147,24 +150,24 @@ def set_power_status(conn, options):
 
 	after_set = True
 
-	if (port_id==None):
+	if port_id == None:
 		eaton_resolv_port_id(conn, options)
 
 	# Controls start at #2 on Switched ePDU, since #1 is the global command
-	if (device.ident_str == "Eaton Switched ePDU"):
+	if device.ident_str == "Eaton Switched ePDU":
 		port_id = int(port_id)+1
 
 	oid = ((device.has_switches) and device.control_oid%(switch_id, port_id) or device.control_oid%(port_id))
 
-	conn.set(oid,(options["--action"]=="on" and device.turn_on or device.turn_off))
+	conn.set(oid, (options["--action"] == "on" and device.turn_on or device.turn_off))
 
 
 def get_outlets_status(conn, options):
 	outletCount = 0
 	result = {}
 
-	if (device==None):
-		eaton_set_device(conn, options)
+	if device == None:
+		eaton_set_device(conn)
 
 	res_ports = conn.walk(device.outlet_table_oid, 30)
 
@@ -175,8 +178,9 @@ def get_outlets_status(conn, options):
 
 		# Plug indexing start from zero, so we substract '1' from the
 		# user's given plug number
-		if (device.ident_str == "Eaton Managed ePDU"):
-			port_num = str(int(((device.has_switches) and "%s:%s"%(t[len(t)-3], t[len(t)-1]) or "%s"%(t[len(t)-1]))) + 1)
+		if device.ident_str == "Eaton Managed ePDU":
+			port_num = str(int(((device.has_switches) and
+					"%s:%s"%(t[len(t)-3], t[len(t)-1]) or "%s"%(t[len(t)-1]))) + 1)
 
 			# Plug indexing start from zero, so we add '1'
 			# for the user's exposed plug number
@@ -190,20 +194,18 @@ def get_outlets_status(conn, options):
 			port_num = str(outletCount)
 			port_name = str(outletCount)
 			port_status = ""
-			if (status != '0'):
+			if status != '0':
 				result[port_num] = (port_name, port_status)
 
 	return result
 
 # Main agent method
 def main():
-	device_opt = [ "ipaddr", "login", "passwd", "no_login", "no_password", \
-		       "port", "snmp_version", "community" ]
+	device_opt = ["ipaddr", "login", "passwd", "no_login", "no_password", \
+		       "port", "snmp_version", "snmp"]
 
 	atexit.register(atexit_handler)
 
-	snmp_define_defaults ()
-
 	all_opt["switch"]["default"] = 1
 	all_opt["power_wait"]["default"] = 2
 	all_opt["snmp_version"]["default"] = "1"
@@ -213,10 +215,10 @@ def main():
 	# Plug indexing start from zero on ePDU Managed, so we substract '1' from
 	# the user's given plug number.
 	# For Switched ePDU, we will add this back again later.
-	if ((options.has_key("--plug")) and (options["--plug"].isdigit())):
+	if options.has_key("--plug") and options["--plug"].isdigit():
 		options["--plug"] = str(int(options["--plug"]) - 1)
 
-	docs = { }
+	docs = {}
 	docs["shortdesc"] = "Fence agent for Eaton over SNMP"
 	docs["longdesc"] = "fence_eaton_snmp is an I/O Fencing agent \
 which can be used with the Eaton network power switch. It logs \
diff --git a/fence/agents/egenera/Makefile.am b/fence/agents/egenera/Makefile.am
deleted file mode 100644
index c69f805..0000000
--- a/fence/agents/egenera/Makefile.am
+++ /dev/null
@@ -1,17 +0,0 @@
-MAINTAINERCLEANFILES	= Makefile.in
-
-TARGET			= fence_egenera
-
-SRC			= $(TARGET).pl
-
-EXTRA_DIST		= $(SRC)
-
-sbin_SCRIPTS		= $(TARGET)
-
-man_MANS		= $(TARGET).8
-
-include $(top_srcdir)/make/fencebuild.mk
-include $(top_srcdir)/make/fencemanperl.mk
-
-clean-local: clean-man
-	rm -f $(TARGET)
diff --git a/fence/agents/egenera/fence_egenera.pl b/fence/agents/egenera/fence_egenera.pl
deleted file mode 100644
index 2ea4d0c..0000000
--- a/fence/agents/egenera/fence_egenera.pl
+++ /dev/null
@@ -1,501 +0,0 @@
-#!/usr/bin/perl
-
-use Getopt::Std;
-use IPC::Open3;
-
-my $ME = $0;
-
-END {
-  defined fileno STDOUT or return;
-  close STDOUT and return;
-  warn "$ME: failed to close standard output: $!\n";
-  $? ||= 1;
-}
-
-# WARNING!! Do not add code bewteen "#BEGIN_VERSION_GENERATION" and 
-# "#END_VERSION_GENERATION"  It is generated by the Makefile
-
-#BEGIN_VERSION_GENERATION
-$RELEASE_VERSION="";
-$REDHAT_COPYRIGHT="";
-$BUILD_DATE="";
-#END_VERSION_GENERATION
-
-# Get the program name from $0 and strip directory names
-$_=$0;
-$|=1;
-s/.*\///;
-my $pname = $_;
-
-$esh="/opt/panmgr/bin/esh";
-
-sub usage 
-{
-	print "Usage:\n";
-	print "\n";
-	print "$pname [options]\n";
-	print "\n";
-	print "Options:\n";
-	print "  -c <string>      cserver\n";
-	print "  -h               help\n";
-	print "  -l <string>      lpan\n";
-	print "  -o <string>      Action: reboot (default), off, on or status\n";
-	print "  -p <string>      pserver\n";
-	print "  -u <string>      username (default=root)\n";
-	print "  -f <seconds>     Wait X seconds before fencing is started\n";
-	print "  -q               quiet mode\n";
-	print "  -V               version\n";
-	
-	exit 0;
-}
-
-sub fail
-{
-	($msg)=@_;
-	print $msg."\n" unless defined $opt_q;
-	$t->close if defined $t;
-	exit 1;
-}
-
-sub fail_usage
-{
-	($msg)=@_;
-	print STDERR $msg."\n" if $msg;
-	print STDERR "Please use '-h' for usage.\n";
-	exit 1;
-}
-
-
-sub version
-{
-	print "$pname $RELEASE_VERSION $BUILD_DATE\n";
-	print "$REDHAT_COPYRIGHT\n" if ( $REDHAT_COPYRIGHT );
-
-	exit 0;
-}
-
-sub print_metadata
-{
-print '<?xml version="1.0" ?>
-<resource-agent name="fence_egenera" shortdesc="I/O Fencing agent for the Egenera BladeFrame" >
-<longdesc>
-fence_egenera  is  an I/O Fencing agent which can be used with the Egenera BladeFrame. It logs into a control blade (cserver) via ssh and operates on a process    ing  blade  (pserver) identified by the pserver name and the logical process area network (LPAN) that it is in. fence_egenera requires that ssh keys have been setup so that the fence_egenera  does not require a password to authenticate. Refer to ssh(8) for more information on setting up ssh keys.
-</longdesc>
-<vendor-url>http://www.bull.com</vendor-url>
-<parameters>
-        <parameter name="action" unique="0" required="1">
-                <getopt mixed="-o [action]" />
-                <content type="string" default="reboot" />
-                <shortdesc lang="en">Fencing Action</shortdesc>
-        </parameter>
-        <parameter name="cserver" unique="0" required="1">
-                <getopt mixed="-c [cserver]" />
-                <content type="string"  />
-                <shortdesc lang="en">The cserver to ssh to. cserver can be in the form user at hostname to specify a different user to login as.</shortdesc>
-        </parameter>
-        <parameter name="pserver" unique="0" required="1">
-                <getopt mixed="-p [pserver]" />
-                <content type="string"  />
-                <shortdesc lang="en">The pserver to operate on.</shortdesc>
-        </parameter>
-        <parameter name="user" unique="0" required="1">
-                <getopt mixed="-u [name]" />
-                <content type="string" default="root" />
-                <shortdesc lang="en">Login Name</shortdesc>
-        </parameter>
-        <parameter name="lpan" unique="0" required="1">
-                <getopt mixed="-l [lpan]" />
-                <content type="string"  />
-                <shortdesc lang="en">The lpan to operate on.</shortdesc>
-        </parameter>
-        <parameter name="delay" unique="0" required="0">
-                <getopt mixed="-f [seconds]" />
-                <content type="string" default="0"/>
-                <shortdesc lang="en">Wait X seconds before fencing is started</shortdesc>
-        </parameter>
-        <parameter name="help" unique="0" required="0">
-                <getopt mixed="-h" />           
-                <content type="string"  />
-                <shortdesc lang="en">Display help and exit</shortdesc>                    
-        </parameter>
-</parameters>
-<actions>
-        <action name="on" />
-        <action name="off" />
-	<action name="reboot" />
-        <action name="status" />
-        <action name="metadata" />
-</actions>
-</resource-agent>
-';
-}
-
-if (@ARGV > 0) 
-{
-	getopts("c:hl:o:p:u:qVf:") || fail_usage ;
-
-	usage if defined $opt_h;
-	version if defined $opt_V;
-
-	fail_usage "Unkown parameter." if (@ARGV > 0);
-
-
-	$cserv  = $opt_c if defined $opt_c;
-	$lpan   = $opt_l if defined $opt_l;
-	$pserv  = $opt_p if defined $opt_p;
-	$action = $opt_o if defined $opt_o;
-	$user   = $opt_u if defined $opt_u;
-	$delay  = $opt_f if defined $opt_f;
-} 
-else 
-{
-	get_options_stdin();
-} 
-
-if (((defined $opt_o) && ($opt_o =~ /metadata/i)) || ((defined $action) && ($action =~ /metadata/i))) {
-	print_metadata();
-	exit 0;
-}
-
-$action = "reboot" unless defined $action;
-$user = "root" unless defined $user;
-
-fail "failed: no cserver defined" unless defined $cserv;
-fail "failed: no lpan defined" unless defined $lpan;
-fail "failed: no pserver defined" unless defined $pserv;
-
-fail "failed: unrecognised action: $action"
-	unless $action =~ /^(off|on|reboot|status|pblade)$/i;
-
-sub get_options_stdin
-{
-	my $opt;
-	my $line = 0;
-	while( defined($in = <>) )
-	{
-		$_ = $in;
-		chomp;
-
-		# strip leading and trailing whitespace
-		s/^\s*//;
-		s/\s*$//;
-
-		# skip comments
-		next if /^#/;
-
-	        $line+=1;
-		$opt=$_;
-		next unless $opt;
-
-		($name,$val)=split /\s*=\s*/, $opt;
-
-		if ( $name eq "" )
-		{
-			print STDERR "parse error: illegal name in option $line\n";
-			exit 2;
-		} 
-
-		elsif ($name eq "agent" )
-		{
-			# DO NOTHING -- this field is used by fenced 
-		}
-
-		elsif ($name eq "cserver" ) 
-		{
-			$cserv = $val;
-		} 
-
-		elsif ($name eq "lpan" ) 
-		{
-			$lpan = $val;
-		} 
-
-		elsif ($name eq "pserver" ) 
-		{
-			$pserv = $val;
-		} 
-
-		elsif ($name eq "action" ) 
-		{
-			$action = $val;
-		} 
-
-		elsif ($name eq "esh" ) 
-		{
-			$esh = $val;
-		} 
-		elsif ($name eq "user" )
-		{
-			$user = $val;
-		}
-		elsif ($name eq "delay" )
-		{
-			$delay = $val;
-		}
-	}
-}
-
-# _pserver_query_field -- query the state of the pBlade or Status field
-# and return it's value in $_.  
-# Return 0 on success, or non-zero on error
-sub _pserver_query_field
-{
-	my ($field,$junk) = @_;
-
-	if ($field ne "pBlade" && $field ne "Status")
-	{
-		$_="Error _pserver_query_field: unknown field of type '$field'";
-		return 1;
-	}
-
-	my $val;
-
-	my $cmd = "ssh -l $user $cserv $esh pserver $lpan/$pserv";
-	my $pid = open3 (\*WTR, \*RDR,\*RDR, $cmd)
-		or die "error open3(): $!";
-
-	while(<RDR>)
-	{
-		chomp;
-		my $line = $_;
-		my @fields = split /\s+/,$line;
-
-		if ($fields[0] eq "Error:")
-		{
-			$val=$line;
-			print "Debug ERROR: $val\n";
-			last;
-		}
-		elsif ($fields[0] eq $pserv)
-		{
-			if ( $field eq "Status" ) 
-			{
-				$val=$fields[1];
-			}
-			elsif ($field eq "pBlade" )
-			{
-				# grrr... Status can be "Shutting down"
-				if ($fields[1] ne "Shutting")
-				{
-					$val=$fields[3];
-				}
-				else
-				{
-					$val=$fields[4];
-				}
-			}
-		}
-	}
-
-	close WTR;
-	close RDR;
-	
-	waitpid $pid,0;
-	my $rtrn = $?>>8;
-	$_=$val if defined $val;
-	return $rtrn;
-}
-
-# return the pBlade of an lpan/pserver in $_.  
-# Return 0 on success or non=zero on error
-sub pserver_pblade
-{
-	_pserver_query_field "pBlade";
-}
-
-# return the Status of an lpan/pserver in $_.  
-# Return 0 on success or non=zero on error
-sub pserver_status
-{
-	_pserver_query_field "Status";
-}
-
-# boot an lpan/pserver.  
-# Return 0  if the status is "Booted" or "Booting" or non-zero on failure.
-# Continue checking the value until the status is "Boot" or "Booting" or
-# until a timeout of 120 seconds has been reached.
-sub pserver_boot
-{
-	my $rtrn=1;
-
-	# It seems it can take a while for a pBlade to 
-	# boot sometimes.  We shall wait for 120 seconds
-	# before giving up on a node returning failure
-	for (my $trys=0; $trys<120; $trys++)
-	{
-		last if (pserver_status != 0);
-
-		my $status = $_;
-		if ( $status eq "Booted"  || $status eq "Booting")
-		{
-			$rtrn=0;
-			last;
-		}
-
-		if(pserver_pblade)
-		{
-			die "error getting pBlade info";
-		}
-
-		# Is there any harm in sending this command multiple times?
-		my $cmd = "ssh -l $user $cserv $esh pserver -b $lpan/$pserv";
-		my $pid = open3 (\*WTR, \*RDR,\*RDR, $cmd)
-			or die "error open3(): $!";
-
-		close WTR;
-		close RDR;
-
-		waitpid $pid,0;
-		$rtrn = $?>>8;
-
-		sleep 1;
-	}
-	return $rtrn;
-}
-
-# boot an lpan/pserver.  
-# Return 0  if the status is "Shutdown" or non-zero on failure.
-# Continue checking the value until the status is "Shutdown" or
-# until a timeout of 20 seconds has been reached.
-sub pserver_shutdown
-{
-	my $rtrn=1;
-	local *egen_log;
-	open(egen_log,">>/@LOGDIR@/fence_egenera.log");
-	print egen_log "Attempting shutdown at ".`date`."\n";
-	for (my $trys=0; $trys<20; $trys++)
-	{
-		last if (pserver_status != 0);
-
-
-		my $status = $_;
-                print egen_log "shutdown: $trys    $status\n";
-		if (/^Shutdown/)
-		{
-			$rtrn=0;
-			last;
-		}
-		elsif (/^Shutting/)
-		{
-			# We are already in the process of shutting down.
-			# do I need to do anything here?  
-			# We'll just wait for now
-		}
-    elsif (/^Booting/)
-    {
-       # Server is already on the way back up. Do nothing
-       $rtrn=0;
-       last;
-    }
-		elsif (/^Booted\(KDB\)/ || /^Debugging/ )
-		{
-			print egen_log "shutdown: crash dump being performed. Waiting\n";
-			$rtrn=0;
-			last;
-		}
-		else
-		{
-			if (pserver_pblade)
-			{
-				die "error getting pBlade info: $_";
-			}
-
-			# is there any harm in sending this command multiple 
-			# times?
-			my $cmd = "ssh -l $user $cserv $esh blade -s $_";
-                        print egen_log "shutdown: $cmd  being called, before open3\n";
-			my $pid = open3 (\*WTR, \*RDR,\*RDR, $cmd)
-				or die "error open3(): $!";
-                        print egen_log "shutdown: after calling open3\n";
-                        @outlines = <RDR>;
-                        print egen_log "shutdown: Open3 result: ", @outlines, "\n";
-
-			close WTR;
-			close RDR;
-
-			waitpid $pid,0;
-			$rtrn = $?>>8;
-		}
-
-		sleep 1;
-	}
-        print egen_log "shutdown: Returning from pserver_shutdown with return code $rtrn\n";
-	return $rtrn;
-}
-
-
-$_=$action;
-if (/^status$/i)
-{
-	if (pserver_status==0)
-	{
-		print "$lpan/$pserv is $_\n" unless defined $opt_q;
-		exit 0;
-	}
-	else
-	{
-		fail "failed to get status of $lpan/$pserv: $_";
-	}
-}
-elsif (/^pblade$/i)
-{
-	if (pserver_pblade==0)
-	{
-		print "$lpan/$pserv is $_\n" unless defined $opt_q;
-		exit 0;
-	}
-	else
-	{
-		fail "failed to get pblade of $lpan/$pserv: $_";
-	}
-}
-elsif (/^off$/i)
-{
-	sleep ($delay) if defined($delay);
-	if (pserver_shutdown==0)
-	{
-		print "success: $lpan/$pserv has been shutdown\n" 
-			unless defined $opt_q;
-		exit 0;
-	}
-	else
-	{
-		fail "failed to shutdown $lpan/$pserv";
-	}
-}
-elsif (/^on$/i)
-{
-	if (pserver_boot==0)
-	{
-		print "success: $lpan/$pserv has been turned on\n" 
-			unless defined $opt_q;
-		exit 0;
-	}
-	else
-	{
-		fail "failed to turn on $lpan/$pserv";
-	}
-}
-elsif (/^reboot$/i)
-{
-	sleep ($delay) if defined($delay);
-	if (pserver_shutdown!=0)
-	{
-		fail "failed to shutdown $lpan/$pserv";
-	}
-
-	if (pserver_boot==0)
-	{
-		print "success: $lpan/$pserv has been rebooted\n" 
-			unless defined $opt_q;
-		exit 0;
-	}
-	else
-	{
-		fail "failed to turn on $lpan/$pserv";
-	}
-}
-else
-{
-	die "unknown action: $action";
-}
diff --git a/fence/agents/apc/Makefile.am b/fence/agents/emerson/Makefile.am
similarity index 63%
copy from fence/agents/apc/Makefile.am
copy to fence/agents/emerson/Makefile.am
index 355c873..f7e5497 100644
--- a/fence/agents/apc/Makefile.am
+++ b/fence/agents/emerson/Makefile.am
@@ -1,6 +1,6 @@
 MAINTAINERCLEANFILES	= Makefile.in
 
-TARGET			= fence_apc
+TARGET			= fence_emerson
 
 SRC			= $(TARGET).py
 
@@ -10,8 +10,8 @@ sbin_SCRIPTS		= $(TARGET)
 
 man_MANS		= $(TARGET).8
 
+FENCE_TEST_ARGS         = -l test -p test -a test -n 1
+
 include $(top_srcdir)/make/fencebuild.mk
 include $(top_srcdir)/make/fenceman.mk
-
-clean-local: clean-man
-	rm -f $(TARGET)
+include $(top_srcdir)/make/agentpycheck.mk
diff --git a/fence/agents/emerson/fence_emerson.py b/fence/agents/emerson/fence_emerson.py
new file mode 100644
index 0000000..a98351a
--- /dev/null
+++ b/fence/agents/emerson/fence_emerson.py
@@ -0,0 +1,68 @@
+#!/usr/bin/python -tt
+
+import sys
+import atexit
+sys.path.append("@FENCEAGENTSLIBDIR@")
+from fencing import *
+from fencing_snmp import FencingSnmp
+
+#BEGIN_VERSION_GENERATION
+RELEASE_VERSION="Emerson SNMP fence agent"
+REDHAT_COPYRIGHT=""
+BUILD_DATE=""
+#END_VERSION_GENERATION
+
+### CONSTANTS ###
+STATUSES_OID = ".1.3.6.1.4.1.476.1.42.3.8.50.20.1.95"
+CONTROL_OID = ".1.3.6.1.4.1.476.1.42.3.8.50.20.1.100"
+NAMES_OID = ".1.3.6.1.4.1.476.1.42.3.8.50.20.1.10"
+
+# Status constants returned as value from SNMP
+STATUS_DOWN = 1
+STATUS_UP = 2
+
+# Status constants to set as value to SNMP
+STATUS_SET_OFF = 0
+STATUS_SET_ON = 1
+
+def get_power_status(conn, options):
+	(_, status) = conn.get("%s.%s"% (STATUSES_OID, options["--plug"]))
+	return status == str(STATUS_UP) and "on" or "off"
+
+def set_power_status(conn, options):
+	conn.set("%s.%s" % (CONTROL_OID, options["--plug"]),
+			(options["--action"] == "on" and STATUS_SET_ON or STATUS_SET_OFF))
+
+def get_outlets_status(conn, _):
+	result = {}
+	res_outlet = conn.walk(STATUSES_OID, 30)
+
+	for outlet_info in res_outlet:
+		port_num = ".".join(outlet_info[0].split('.')[-3:])
+		port_alias = conn.get("%s.%s"% (NAMES_OID, port_num))[1]
+		port_status = (outlet_info[1] == str(STATUS_UP) and "on" or "off")
+		result[port_num] = (port_alias, port_status)
+	return result
+
+def main():
+	device_opt = ["ipaddr", "login", "passwd", "no_login", "no_password", \
+		       "port", "snmp_version", "snmp"]
+
+	atexit.register(atexit_handler)
+
+	all_opt["power_wait"]["default"] = "5"
+	options = check_input(device_opt, process_input(device_opt))
+
+	docs = {}
+	docs["shortdesc"] = "Fence agent for Emerson over SNMP"
+	docs["longdesc"] = "fence_emerson is an I/O Fencing agent \
+	which can be used with MPX and MPH2 managed rack PDU."
+	docs["vendorurl"] = "http://www.emersonnetworkpower.com"
+	show_docs(options, docs)
+
+	# Operate the fencing device
+	result = fence_action(FencingSnmp(options), options, set_power_status, get_power_status, get_outlets_status)
+
+	sys.exit(result)
+if __name__ == "__main__":
+	main()
diff --git a/fence/agents/eps/Makefile.am b/fence/agents/eps/Makefile.am
index 59fdd07..c3d6762 100644
--- a/fence/agents/eps/Makefile.am
+++ b/fence/agents/eps/Makefile.am
@@ -10,8 +10,8 @@ sbin_SCRIPTS		= $(TARGET)
 
 man_MANS		= $(TARGET).8
 
+FENCE_TEST_ARGS         = -l test -p test -a test -n 1
+
 include $(top_srcdir)/make/fencebuild.mk
 include $(top_srcdir)/make/fenceman.mk
-
-clean-local: clean-man
-	rm -f $(TARGET)
+include $(top_srcdir)/make/agentpycheck.mk
diff --git a/fence/agents/eps/fence_eps.py b/fence/agents/eps/fence_eps.py
index 0e7709d..9e31207 100644
--- a/fence/agents/eps/fence_eps.py
+++ b/fence/agents/eps/fence_eps.py
@@ -1,12 +1,15 @@
-#!/usr/bin/python
+#!/usr/bin/python -tt
 
 # The Following Agent Has Been Tested On:
 # ePowerSwitch 8M+ version 1.0.0.4
 
 import sys, re
 import httplib, base64, string, socket
+import logging
+import atexit
 sys.path.append("@FENCEAGENTSLIBDIR@")
 from fencing import *
+from fencing import fail, fail_usage, EC_LOGIN_DENIED, EC_TIMED_OUT, run_delay
 
 #BEGIN_VERSION_GENERATION
 RELEASE_VERSION="ePowerSwitch 8M+ (eps)"
@@ -14,11 +17,6 @@ REDHAT_COPYRIGHT=""
 BUILD_DATE=""
 #END_VERSION_GENERATION
 
-# Log actions and results from EPS device
-def eps_log(options, str):
-	if options["log"] >= LOG_MODE_VERBOSE:
-		options["debug_fh"].write(str)
-
 # Run command on EPS device.
 # @param options Device options
 # @param params HTTP GET parameters (without ?)
@@ -29,35 +27,34 @@ def eps_run_command(options, params):
 
 		request_str = "/"+options["--page"]
 
-		if (params!=""):
+		if params != "":
 			request_str += "?"+params
 
-		eps_log(options, "GET "+request_str+"\n")
+		logging.debug("GET %s\n", request_str)
 		conn.putrequest('GET', request_str)
 
-		if (options.has_key("--username")):
-			if (not options.has_key("--password")):
+		if options.has_key("--username"):
+			if not options.has_key("--password"):
 				options["--password"] = "" # Default is empty password
-				
+
 			# String for Authorization header
 			auth_str = 'Basic ' + string.strip(base64.encodestring(options["--username"]+':'+options["--password"]))
-			eps_log(options, "Authorization:"+auth_str+"\n")
+			logging.debug("Authorization: %s\n", auth_str)
 			conn.putheader('Authorization', auth_str)
 
 		conn.endheaders()
 
 		response = conn.getresponse()
 
-		eps_log(options, "%d %s\n"%(response.status, response.reason))
+		logging.debug("%d %s\n", response.status, response.reason)
 
 		#Response != OK -> couldn't login
-		if (response.status!=200):
+		if response.status != 200:
 			fail(EC_LOGIN_DENIED)
 
 		result = response.read()
-		eps_log(options, result+"\n")
+		logging.debug("%s \n", result)
 		conn.close()
-
 	except socket.timeout:
 		fail(EC_TIMED_OUT)
 	except socket.error:
@@ -66,15 +63,16 @@ def eps_run_command(options, params):
 	return result
 
 def get_power_status(conn, options):
-	ret_val = eps_run_command(options,"")
+	del conn
+	ret_val = eps_run_command(options, "")
 
 	result = {}
-	status = re.findall("p(\d{2})=(0|1)\s*\<br\>", ret_val.lower())
+	status = re.findall(r"p(\d{2})=(0|1)\s*\<br\>", ret_val.lower())
 	for out_num, out_stat in status:
-		result[out_num] = ("",(out_stat=="1" and "on" or "off"))
+		result[out_num] = ("", (out_stat == "1" and "on" or "off"))
 
-	if (not (options["--action"] in ['monitor','list'])):
-		if (not (options["--plug"] in result)):
+	if not options["--action"] in ['monitor', 'list']:
+		if not options["--plug"] in result:
 			fail_usage("Failed: You have to enter existing physical plug!")
 		else:
 			return result[options["--plug"]][1]
@@ -82,7 +80,8 @@ def get_power_status(conn, options):
 		return result
 
 def set_power_status(conn, options):
-	ret_val = eps_run_command(options, "P%s=%s"%(options["--plug"], (options["--action"]=="on" and "1" or "0")))
+	del conn
+	eps_run_command(options, "P%s=%s"%(options["--plug"], (options["--action"] == "on" and "1" or "0")))
 
 # Define new option
 def eps_define_new_opts():
@@ -98,8 +97,8 @@ def eps_define_new_opts():
 
 # Starting point of fence agent
 def main():
-	device_opt = [  "ipaddr", "login", "passwd", "no_login", "no_password", \
-			"port", "hidden_page" ]
+	device_opt = ["ipaddr", "login", "passwd", "no_login", "no_password", \
+			"port", "hidden_page", "web"]
 
 	atexit.register(atexit_handler)
 
@@ -107,8 +106,8 @@ def main():
 
 	options = check_input(device_opt, process_input(device_opt))
 
-	docs = { }           
-	docs["shortdesc"] = "Fence agent for ePowerSwitch" 
+	docs = {}
+	docs["shortdesc"] = "Fence agent for ePowerSwitch"
 	docs["longdesc"] = "fence_eps  is an I/O Fencing agent \
 which can be used with the ePowerSwitch 8M+ power switch to fence \
 connected machines. Fence agent works ONLY on 8M+ device, because \
@@ -120,6 +119,7 @@ page feature must be enabled and properly configured."
 	docs["vendorurl"] = "http://www.epowerswitch.com"
 	show_docs(options, docs)
 
+	run_delay(options)
 	#Run fence action. Conn is None, beacause we always need open new http connection
 	result = fence_action(None, options, set_power_status, get_power_status, get_power_status)
 
diff --git a/fence/agents/hds_cb/Makefile.am b/fence/agents/hds_cb/Makefile.am
index 0763d5a..f36fca1 100644
--- a/fence/agents/hds_cb/Makefile.am
+++ b/fence/agents/hds_cb/Makefile.am
@@ -10,8 +10,8 @@ sbin_SCRIPTS		= $(TARGET)
 
 man_MANS		= $(TARGET).8
 
+FENCE_TEST_ARGS         = -l test -p test -a test -n 1
+
 include $(top_srcdir)/make/fencebuild.mk
 include $(top_srcdir)/make/fenceman.mk
-
-clean-local: clean-man
-	rm -f $(TARGET)
+include $(top_srcdir)/make/agentpycheck.mk
diff --git a/fence/agents/hds_cb/fence_hds_cb.py b/fence/agents/hds_cb/fence_hds_cb.py
index 0e15af3..5de8e2a 100755
--- a/fence/agents/hds_cb/fence_hds_cb.py
+++ b/fence/agents/hds_cb/fence_hds_cb.py
@@ -1,4 +1,4 @@
-#!/usr/bin/python
+#!/usr/bin/python -tt
 
 #####
 ##
@@ -10,7 +10,8 @@
 ##
 #####
 
-import sys, re, pexpect, exceptions
+import sys, re
+import atexit
 sys.path.append("@FENCEAGENTSLIBDIR@")
 from fencing import *
 
@@ -20,15 +21,15 @@ REDHAT_COPYRIGHT=""
 BUILD_DATE="November, 2012"
 #END_VERSION_GENERATION
 
-RE_STATUS_LINE = "^([0-9]+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+).*$"
+RE_STATUS_LINE = r"^([0-9]+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+).*$"
 
 def get_power_status(conn, options):
 	#### Maybe should put a conn.log_expect here to make sure
 	#### we have properly entered into the main menu
 	conn.sendline("S")	# Enter System Command Mode
-	conn.log_expect(options, "SVP>", int(options["--shell-timeout"]))
+	conn.log_expect("SVP>", int(options["--shell-timeout"]))
 	conn.sendline("PC")	# Enter partition control
-	conn.log_expect(options, options["--command-prompt"], int(options["--shell-timeout"]))
+	conn.log_expect(options["--command-prompt"], int(options["--shell-timeout"]))
 	result = {}
 	# Status can now be obtained from the output of the PC
 	# command. Line looks like the following:
@@ -38,9 +39,9 @@ def get_power_status(conn, options):
 	for line in conn.before.splitlines():
 		# populate the relevant fields based on regex
 		partition = re.search(RE_STATUS_LINE, line)
-		if( partition != None):
+		if partition != None:
 			# find the blade number defined in args
-			if( partition.group(1) == options["--plug"] ):
+			if partition.group(1) == options["--plug"]:
 				result = partition.group(2).lower()
 	# We must make sure we go back to the main menu as the
 	# status is checked before any fencing operations are
@@ -48,9 +49,9 @@ def get_power_status(conn, options):
 	# the partition control, but the logic is a little cleaner
 	# this way.
 	conn.sendline("Q")	# Back to system command mode
-	conn.log_expect(options, "SVP>", int(options["--shell-timeout"]))
+	conn.log_expect("SVP>", int(options["--shell-timeout"]))
 	conn.sendline("EX")	# Back to system console main menu
-	conn.log_expect(options, options["--command-prompt"], int(options["--shell-timeout"]))
+	conn.log_expect(options["--command-prompt"], int(options["--shell-timeout"]))
 
 	return result
 
@@ -60,36 +61,35 @@ def set_power_status(conn, options):
 		'off': "F",
 		'reboot' : "H",
 	}[options["--action"]]
-	
 
 	conn.sendline("S")	# Enter System Command Mode
-	conn.log_expect(options, "SVP>", int(options["--shell-timeout"]))
+	conn.log_expect("SVP>", int(options["--shell-timeout"]))
 	conn.sendline("PC")	# Enter partition control
-	conn.log_expect(options, options["--command-prompt"], int(options["--shell-timeout"]))
+	conn.log_expect(options["--command-prompt"], int(options["--shell-timeout"]))
 	conn.sendline("P")	# Enter power control menu
-	conn.log_expect(options, options["--command-prompt"], int(options["--shell-timeout"]))
+	conn.log_expect(options["--command-prompt"], int(options["--shell-timeout"]))
 	conn.sendline(action)	# Execute action from array above
-	conn.log_expect(options, options["--command-prompt"], int(options["--shell-timeout"]))
+	conn.log_expect(options["--command-prompt"], int(options["--shell-timeout"]))
 	conn.sendline(options["--plug"]) # Select blade number from args
-	conn.log_expect(options, options["--command-prompt"], int(options["--shell-timeout"]))
+	conn.log_expect(options["--command-prompt"], int(options["--shell-timeout"]))
 	conn.sendline("Y")	# Confirm action
-	conn.log_expect(options, "Hit enter key.", int(options["--shell-timeout"]))
+	conn.log_expect("Hit enter key.", int(options["--shell-timeout"]))
 	conn.sendline("")	# Press the any key
-	conn.log_expect(options, options["--command-prompt"], int(options["--shell-timeout"]))
+	conn.log_expect(options["--command-prompt"], int(options["--shell-timeout"]))
 	conn.sendline("Q")	# Quit back to partition control
-	conn.log_expect(options, options["--command-prompt"], int(options["--shell-timeout"]))
+	conn.log_expect(options["--command-prompt"], int(options["--shell-timeout"]))
 	conn.sendline("Q")	# Quit back to system command mode
-	conn.log_expect(options, "SVP>", int(options["--shell-timeout"]))
+	conn.log_expect("SVP>", int(options["--shell-timeout"]))
 	conn.sendline("EX")	# Quit back to system console menu
-	conn.log_expect(options, options["--command-prompt"], int(options["--shell-timeout"]))
+	conn.log_expect(options["--command-prompt"], int(options["--shell-timeout"]))
 
 def get_blades_list(conn, options):
-	outlets = { }
+	outlets = {}
 
 	conn.sendline("S")	# Enter System Command Mode
-	conn.log_expect(options, "SVP>", int(options["--shell-timeout"]))
+	conn.log_expect("SVP>", int(options["--shell-timeout"]))
 	conn.sendline("PC")	# Enter partition control
-	conn.log_expect(options, options["--command-prompt"], int(options["--shell-timeout"]))
+	conn.log_expect(options["--command-prompt"], int(options["--shell-timeout"]))
 	# Status can now be obtained from the output of the PC
 	# command. Line looks like the following:
 	# "P Power        Condition     LID lamp Mode  Auto power on"
@@ -97,49 +97,41 @@ def get_blades_list(conn, options):
 	# "1 On           Normal        Off      Basic Synchronized"
 	for line in conn.before.splitlines():
 		partition = re.search(RE_STATUS_LINE, line)
-		if( partition != None):
-			outlets[partition.group(1)] = (partition.group(2), "")	
+		if partition != None:
+			outlets[partition.group(1)] = (partition.group(2), "")
 	conn.sendline("Q")	# Quit back to system command mode
-	conn.log_expect(options, "SVP>", int(options["--shell-timeout"]))
+	conn.log_expect("SVP>", int(options["--shell-timeout"]))
 	conn.sendline("EX")	# Quit back to system console menu
-	conn.log_expect(options, options["--command-prompt"], int(options["--shell-timeout"]))
+	conn.log_expect(options["--command-prompt"], int(options["--shell-timeout"]))
 
 	return outlets
 
 def main():
-	device_opt = [  "ipaddr", "login", "passwd", "cmd_prompt", "secure", \
-			"port", "missing_as_off" ]
+	device_opt = ["ipaddr", "login", "passwd", "cmd_prompt", "secure", \
+			"port", "missing_as_off", "telnet"]
 
 	atexit.register(atexit_handler)
 
 	all_opt["power_wait"]["default"] = "5"
-	all_opt["cmd_prompt"]["default"] = [ "\) :" ]
+	all_opt["cmd_prompt"]["default"] = [r"\) :"]
 
 	options = check_input(device_opt, process_input(device_opt))
 
-	docs = { }
+	docs = {}
 	docs["shortdesc"] = "Fence agent for Hitachi Compute Blade systems"
 	docs["longdesc"] = "fence_hds_cb is an I/O Fencing agent \
 which can be used with Hitachi Compute Blades with recent enough firmware that \
 includes telnet support."
 	docs["vendorurl"] = "http://www.hds.com"
 	show_docs(options, docs)
-	
+
 	##
 	## Operate the fencing device
 	######
 	conn = fence_login(options)
 	result = fence_action(conn, options, set_power_status, get_power_status, get_blades_list)
 
-	##
-	## Logout from system
-	######
-	try:
-		conn.sendline("X")
-		conn.close()
-	except:
-		pass
-	
+	fence_logout(conn, "X")
 	sys.exit(result)
 
 if __name__ == "__main__":
diff --git a/fence/agents/hpblade/Makefile.am b/fence/agents/hpblade/Makefile.am
index e8ae6ff..a5fc2b1 100644
--- a/fence/agents/hpblade/Makefile.am
+++ b/fence/agents/hpblade/Makefile.am
@@ -10,8 +10,8 @@ sbin_SCRIPTS		= $(TARGET)
 
 man_MANS		= $(TARGET).8
 
+FENCE_TEST_ARGS         = -l test -p test -a test -n 1
+
 include $(top_srcdir)/make/fencebuild.mk
 include $(top_srcdir)/make/fenceman.mk
-
-clean-local: clean-man
-	rm -f $(TARGET)
+include $(top_srcdir)/make/agentpycheck.mk
diff --git a/fence/agents/hpblade/fence_hpblade.py b/fence/agents/hpblade/fence_hpblade.py
index 42f5309..e73a6c3 100644
--- a/fence/agents/hpblade/fence_hpblade.py
+++ b/fence/agents/hpblade/fence_hpblade.py
@@ -1,4 +1,4 @@
-#!/usr/bin/python
+#!/usr/bin/python -tt
 
 #####
 ##
@@ -6,9 +6,11 @@
 ##  * BladeSystem c7000 Enclosure
 #####
 
-import sys, re, pexpect, exceptions
+import sys, re
+import atexit
 sys.path.append("@FENCEAGENTSLIBDIR@")
 from fencing import *
+from fencing import fail, EC_STATUS
 
 #BEGIN_VERSION_GENERATION
 RELEASE_VERSION="New Bladecenter Agent - test release on steroids"
@@ -18,9 +20,9 @@ BUILD_DATE="March, 2008"
 
 def get_power_status(conn, options):
 	conn.send_eol("show server status " + options["--plug"])
-	conn.log_expect(options, options["--command-prompt"] , int(options["--shell-timeout"]))
-		
-	power_re = re.compile("^\s*Power: (.*?)\s*$")
+	conn.log_expect(options["--command-prompt"], int(options["--shell-timeout"]))
+
+	power_re = re.compile(r"^\s*Power: (.*?)\s*$")
 	status = "unknown"
 	for line in conn.before.splitlines():
 		res = power_re.search(line)
@@ -40,15 +42,15 @@ def set_power_status(conn, options):
 		conn.send_eol("poweron server " + options["--plug"])
 	elif options["--action"] == "off":
 		conn.send_eol("poweroff server " + options["--plug"] + " force")
-	conn.log_expect(options, options["--command-prompt"], int(options["--shell-timeout"]))
+	conn.log_expect(options["--command-prompt"], int(options["--shell-timeout"]))
 
 def get_blades_list(conn, options):
-	outlets = { }
+	outlets = {}
 
-	conn.send_eol("show server list" )
-	conn.log_expect(options, options["--command-prompt"], int(options["--shell-timeout"]))
+	conn.send_eol("show server list")
+	conn.log_expect(options["--command-prompt"], int(options["--shell-timeout"]))
 
-	list_re = re.compile("^\s*(.*?)\s+(.*?)\s+(.*?)\s+OK\s+(.*?)\s+(.*?)\s*$")
+	list_re = re.compile(r"^\s*(.*?)\s+(.*?)\s+(.*?)\s+OK\s+(.*?)\s+(.*?)\s*$")
 	for line in conn.before.splitlines():
 		res = list_re.search(line)
 		if res != None:
@@ -57,38 +59,30 @@ def get_blades_list(conn, options):
 	return outlets
 
 def main():
-	device_opt = [ "ipaddr", "login", "passwd", "cmd_prompt", "secure", "port", "missing_as_off" ]
+	device_opt = ["ipaddr", "login", "passwd", "cmd_prompt", "secure", \
+		"port", "missing_as_off", "telnet"]
 
 	atexit.register(atexit_handler)
 
-	all_opt["cmd_prompt"]["default"] = [ "c7000oa>" ]
+	all_opt["cmd_prompt"]["default"] = ["c7000oa>"]
 
 	options = check_input(device_opt, process_input(device_opt))
 
-	docs = { }        
+	docs = {}
 	docs["shortdesc"] = "Fence agent for HP BladeSystem"
 	docs["longdesc"] = "fence_hpblade is an I/O Fencing agent \
 which can be used with HP BladeSystem. It logs into an enclosure via telnet or ssh \
 and uses the command line interface to power on and off blades."
 	docs["vendorurl"] = "http://www.hp.com"
 	show_docs(options, docs)
-	
+
 	##
 	## Operate the fencing device
 	######
 	options["eol"] = "\n"
 	conn = fence_login(options)
 	result = fence_action(conn, options, set_power_status, get_power_status, get_blades_list)
-
-	##
-	## Logout from system
-	######
-	try:
-		conn.send_eol("exit")
-		conn.close()
-	except:
-		pass
-	
+	fence_logout(conn, "exit")
 	sys.exit(result)
 
 if __name__ == "__main__":
diff --git a/fence/agents/ibmblade/Makefile.am b/fence/agents/ibmblade/Makefile.am
index f1c94de..47b83d7 100644
--- a/fence/agents/ibmblade/Makefile.am
+++ b/fence/agents/ibmblade/Makefile.am
@@ -10,8 +10,8 @@ sbin_SCRIPTS		= $(TARGET)
 
 man_MANS		= $(TARGET).8
 
+FENCE_TEST_ARGS		= -l test -p test -a test -n 1
+
 include $(top_srcdir)/make/fencebuild.mk
 include $(top_srcdir)/make/fenceman.mk
-
-clean-local: clean-man
-	rm -f $(TARGET)
+include $(top_srcdir)/make/agentpycheck.mk
diff --git a/fence/agents/ibmblade/fence_ibmblade.py b/fence/agents/ibmblade/fence_ibmblade.py
index 1787ae2..b4810a5 100644
--- a/fence/agents/ibmblade/fence_ibmblade.py
+++ b/fence/agents/ibmblade/fence_ibmblade.py
@@ -1,9 +1,10 @@
-#!/usr/bin/python
+#!/usr/bin/python -tt
 
 import sys
+import atexit
 sys.path.append("@FENCEAGENTSLIBDIR@")
 from fencing import *
-from fencing_snmp import *
+from fencing_snmp import FencingSnmp
 
 #BEGIN_VERSION_GENERATION
 RELEASE_VERSION="IBM Blade SNMP fence agent"
@@ -14,7 +15,7 @@ BUILD_DATE=""
 ### CONSTANTS ###
 # From fence_ibmblade.pl
 STATUSES_OID = ".1.3.6.1.4.1.2.3.51.2.22.1.5.1.1.4" # remoteControlBladePowerState
-CONTROL_OID  = ".1.3.6.1.4.1.2.3.51.2.22.1.6.1.1.7" # powerOnOffBlade
+CONTROL_OID = ".1.3.6.1.4.1.2.3.51.2.22.1.6.1.1.7" # powerOnOffBlade
 
 # Status constants returned as value from SNMP
 STATUS_DOWN = 0
@@ -28,10 +29,11 @@ STATUS_SET_ON = 1
 
 def get_power_status(conn, options):
 	(_, status) = conn.get("%s.%s"% (STATUSES_OID, options["--plug"]))
-	return (status == str(STATUS_UP) and "on" or "off")
+	return status == str(STATUS_UP) and "on" or "off"
 
 def set_power_status(conn, options):
-	conn.set("%s.%s"%(CONTROL_OID, options["--plug"]), (options["--action"]=="on" and STATUS_SET_ON or STATUS_SET_OFF))
+	conn.set("%s.%s" % (CONTROL_OID, options["--plug"]),
+			(options["--action"] == "on" and STATUS_SET_ON or STATUS_SET_OFF))
 
 def get_outlets_status(conn, _):
 	result = {}
@@ -42,7 +44,7 @@ def get_outlets_status(conn, _):
 		port_num = blade_info[0].split('.')[-1]
 
 		port_alias = ""
-		port_status = (blade_info[1]==str(STATUS_UP) and "on" or "off")
+		port_status = (blade_info[1] == str(STATUS_UP) and "on" or "off")
 
 		result[port_num] = (port_alias, port_status)
 
@@ -50,17 +52,16 @@ def get_outlets_status(conn, _):
 
 # Main agent method
 def main():
-	device_opt = [ "ipaddr", "login", "passwd", "no_login", "no_password", \
-		       "port", "snmp_version", "community" ]
+	device_opt = ["ipaddr", "login", "passwd", "no_login", "no_password", \
+		       "port", "snmp_version", "snmp"]
 
 	atexit.register(atexit_handler)
 
-	snmp_define_defaults()
 	all_opt["snmp_version"]["default"] = "1"
 
 	options = check_input(device_opt, process_input(device_opt))
 
-	docs = { }
+	docs = {}
 	docs["shortdesc"] = "Fence agent for IBM BladeCenter over SNMP"
 	docs["longdesc"] = "fence_ibmblade is an I/O Fencing agent \
 which can be used with IBM BladeCenter chassis. It issues SNMP Set \
diff --git a/fence/agents/ifmib/Makefile.am b/fence/agents/ifmib/Makefile.am
index a07f264..74ba950 100644
--- a/fence/agents/ifmib/Makefile.am
+++ b/fence/agents/ifmib/Makefile.am
@@ -11,8 +11,8 @@ sbin_SCRIPTS		= $(TARGET)
 
 man_MANS		= $(TARGET).8
 
+FENCE_TEST_ARGS         = -l test -p test -a test -n 1
+
 include $(top_srcdir)/make/fencebuild.mk
 include $(top_srcdir)/make/fenceman.mk
-
-clean-local: clean-man
-	rm -f $(TARGET)
+include $(top_srcdir)/make/agentpycheck.mk
diff --git a/fence/agents/ifmib/fence_ifmib.py b/fence/agents/ifmib/fence_ifmib.py
index 2184a85..7df7683 100644
--- a/fence/agents/ifmib/fence_ifmib.py
+++ b/fence/agents/ifmib/fence_ifmib.py
@@ -1,4 +1,4 @@
-#!/usr/bin/python
+#!/usr/bin/python -tt
 
 # The Following agent has been tested on:
 # - Cisco MDS UROS 9134 FC (1 Slot) Chassis ("1/2/4 10 Gbps FC/Supervisor-2") Motorola, e500v2
@@ -9,9 +9,11 @@
 #   Only lance if is visible
 
 import sys
+import atexit
 sys.path.append("@FENCEAGENTSLIBDIR@")
 from fencing import *
-from fencing_snmp import *
+from fencing import fail_usage, array_to_dict
+from fencing_snmp import FencingSnmp
 
 #BEGIN_VERSION_GENERATION
 RELEASE_VERSION="IF:MIB SNMP fence agent"
@@ -40,17 +42,17 @@ port_num = None
 def port2index(conn, port):
 	res = None
 
-	if (port.isdigit()):
+	if port.isdigit():
 		res = int(port)
 	else:
 		ports = conn.walk(PORTS_OID, 30)
 
 		for x in ports:
-			if (x[1].strip('"')==port):
+			if x[1].strip('"') == port:
 				res = int(x[0].split('.')[-1])
 				break
 
-	if (res==None):
+	if res == None:
 		fail_usage("Can't find port with name %s!"%(port))
 
 	return res
@@ -58,24 +60,19 @@ def port2index(conn, port):
 def get_power_status(conn, options):
 	global port_num
 
-	if (port_num==None):
+	if port_num == None:
 		port_num = port2index(conn, options["--plug"])
 
-	(oid, status) = conn.get("%s.%d"%(STATUSES_OID, port_num))
-	return (status==str(STATUS_UP) and "on" or "off")
+	(_, status) = conn.get("%s.%d"%(STATUSES_OID, port_num))
+	return status == str(STATUS_UP) and "on" or "off"
 
 def set_power_status(conn, options):
 	global port_num
 
-	if (port_num==None):
+	if port_num == None:
 		port_num = port2index(conn, options["--plug"])
 
-	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(map(lambda y:[y[0].split('.')[-1], y[1]], ar))
+	conn.set("%s.%d" % (STATUSES_OID, port_num), (options["--action"] == "on" and STATUS_UP or STATUS_DOWN))
 
 def get_outlets_status(conn, options):
 	result = {}
@@ -84,10 +81,10 @@ def get_outlets_status(conn, options):
 	res_aliases = array_to_dict(conn.walk(ALIASES_OID, 30))
 
 	for x in res_fc:
-		port_num = x[0].split('.')[-1]
+		port_number = x[0].split('.')[-1]
 
 		port_name = x[1].strip('"')
-		port_alias = (res_aliases.has_key(port_num) and res_aliases[port_num].strip('"') or "")
+		port_alias = (res_aliases.has_key(port_number) and res_aliases[port_number].strip('"') or "")
 		port_status = ""
 		result[port_name] = (port_alias, port_status)
 
@@ -95,17 +92,16 @@ def get_outlets_status(conn, options):
 
 # Main agent method
 def main():
-	device_opt = [ "fabric_fencing", "ipaddr", "login", "passwd", "no_login", "no_password", \
-		       "port", "snmp_version", "community" ]
+	device_opt = ["fabric_fencing", "ipaddr", "login", "passwd", "no_login", "no_password", \
+		       "port", "snmp_version", "snmp"]
 
 	atexit.register(atexit_handler)
 
-	snmp_define_defaults ()
 	all_opt["snmp_version"]["default"] = "2c"
 
 	options = check_input(device_opt, process_input(device_opt))
 
-	docs = { }
+	docs = {}
 	docs["shortdesc"] = "Fence agent for IF MIB"
 	docs["longdesc"] = "fence_ifmib is an I/O Fencing agent \
 which can be used with any SNMP IF-MIB capable device. \
@@ -119,7 +115,7 @@ to control the state of an interface."
 
 	# Operate the fencing device
 	result = fence_action(FencingSnmp(options), options, set_power_status, get_power_status, get_outlets_status)
-	
+
 	sys.exit(result)
 
 if __name__ == "__main__":
diff --git a/fence/agents/ilo/Makefile.am b/fence/agents/ilo/Makefile.am
index 8df9a39..c8bdf63 100644
--- a/fence/agents/ilo/Makefile.am
+++ b/fence/agents/ilo/Makefile.am
@@ -12,12 +12,11 @@ sbin_SCRIPTS		= $(TARGET) $(SYMTARGET)
 
 man_MANS		= $(TARGET).8 $(SYMTARGET).8
 
+FENCE_TEST_ARGS         = -l test -p test -a test
+
 $(SYMTARGET): $(TARGET)
 	cp $^ $@
 
-
 include $(top_srcdir)/make/fencebuild.mk
 include $(top_srcdir)/make/fenceman.mk
-
-clean-local: clean-man
-	rm -f $(TARGET) $(SYMTARGET)
+include $(top_srcdir)/make/agentpycheck.mk
diff --git a/fence/agents/ilo/fence_ilo.py b/fence/agents/ilo/fence_ilo.py
index ab6e342..692f317 100644
--- a/fence/agents/ilo/fence_ilo.py
+++ b/fence/agents/ilo/fence_ilo.py
@@ -1,4 +1,4 @@
-#!/usr/bin/python
+#!/usr/bin/python -tt
 
 #####
 ##
@@ -7,14 +7,16 @@
 ##  iLO Version
 ## +---------------------------------------------+
 ##  iLO  / firmware 1.91 / RIBCL 2.22
-##  iLO2 / firmware 1.22 / RIBCL 2.22 
+##  iLO2 / firmware 1.22 / RIBCL 2.22
 ##  iLO2 / firmware 1.50 / RIBCL 2.22
 #####
 
 import sys, re, pexpect
+import atexit
 from xml.sax.saxutils import quoteattr
 sys.path.append("@FENCEAGENTSLIBDIR@")
 from fencing import *
+from fencing import fail, EC_LOGIN_DENIED
 
 #BEGIN_VERSION_GENERATION
 RELEASE_VERSION="New ILO Agent - test release on steroids"
@@ -27,7 +29,7 @@ def get_power_status(conn, options):
 		" PASSWORD = " + quoteattr(options["--password"]) + ">\r\n")
 	conn.send("<SERVER_INFO MODE = \"read\"><GET_HOST_POWER_STATUS/>\r\n")
 	conn.send("</SERVER_INFO></LOGIN>\r\n")
-	conn.log_expect(options, "HOST_POWER=\"(.*?)\"", int(options["--power-timeout"]))
+	conn.log_expect("HOST_POWER=\"(.*?)\"", int(options["--power-timeout"]))
 
 	status = conn.match.group(1)
 	return status.lower().strip()
@@ -37,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:
@@ -60,10 +62,10 @@ def define_new_opts():
 		"help" : "-r, --ribcl-version=[version]  Force ribcl version to use",
 		"required" : "0",
 		"shortdesc" : "Force ribcl version to use",
-		"order" : 1 }
+		"order" : 1}
 
 def main():
-	device_opt = [ "ipaddr", "login", "passwd", "ssl", "ribcl" ]
+	device_opt = ["ipaddr", "login", "passwd", "ssl", "notls", "tls1.0", "ribcl"]
 
 	atexit.register(atexit_handler)
 
@@ -75,7 +77,7 @@ def main():
 
 	options = check_input(device_opt, process_input(device_opt))
 
-	docs = { }
+	docs = {}
 	docs["shortdesc"] = "Fence agent for HP iLO"
 	docs["longdesc"] = "fence_ilo is an I/O Fencing agent \
 used for HP servers with the Integrated Light Out (iLO) PCI card.\
@@ -92,9 +94,9 @@ the iLO card through an XML stream."
 	conn = fence_login(options)
 	try:
 		conn.send("<?xml version=\"1.0\"?>\r\n")
-		conn.log_expect(options, [ "</RIBCL>", "<END_RIBCL/>" ], int(options["--login-timeout"]))
+		conn.log_expect(["</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:
@@ -107,10 +109,12 @@ the iLO card through an XML stream."
 		if options["--ribcl-version"] >= 2:
 			conn.send("<RIB_INFO MODE=\"read\"><GET_FW_VERSION />\r\n")
 			conn.send("</RIB_INFO>\r\n")
-			conn.log_expect(options, "<GET_FW_VERSION\s*\n", int(options["--shell-timeout"]))
-			conn.log_expect(options, "/>", int(options["--shell-timeout"]))
-			options["fw_version"] = float(re.compile("FIRMWARE_VERSION\s*=\s*\"(.*?)\"", re.IGNORECASE).search(conn.before).group(1))
-			options["fw_processor"] = re.compile("MANAGEMENT_PROCESSOR\s*=\s*\"(.*?)\"", re.IGNORECASE).search(conn.before).group(1)
+			conn.log_expect(r"<GET_FW_VERSION\s*\n", int(options["--shell-timeout"]))
+			conn.log_expect("/>", int(options["--shell-timeout"]))
+			options["fw_version"] = float(re.compile(r"FIRMWARE_VERSION\s*=\s*\"(.*?)\"",
+					re.IGNORECASE).search(conn.before).group(1))
+			options["fw_processor"] = re.compile(r"MANAGEMENT_PROCESSOR\s*=\s*\"(.*?)\"",
+					re.IGNORECASE).search(conn.before).group(1)
 		conn.send("</LOGIN>\r\n")
 	except pexpect.TIMEOUT:
 		fail(EC_LOGIN_DENIED)
@@ -121,7 +125,7 @@ the iLO card through an XML stream."
 	## Fence operations
 	####
 	result = fence_action(conn, options, set_power_status, get_power_status, None)
-	
+
 	sys.exit(result)
 
 if __name__ == "__main__":
diff --git a/fence/agents/apc/Makefile.am b/fence/agents/ilo_moonshot/Makefile.am
similarity index 62%
copy from fence/agents/apc/Makefile.am
copy to fence/agents/ilo_moonshot/Makefile.am
index 355c873..d6e12d7 100644
--- a/fence/agents/apc/Makefile.am
+++ b/fence/agents/ilo_moonshot/Makefile.am
@@ -1,6 +1,6 @@
 MAINTAINERCLEANFILES	= Makefile.in
 
-TARGET			= fence_apc
+TARGET			= fence_ilo_moonshot
 
 SRC			= $(TARGET).py
 
@@ -10,8 +10,8 @@ sbin_SCRIPTS		= $(TARGET)
 
 man_MANS		= $(TARGET).8
 
+FENCE_TEST_ARGS         = -l test -p test -a test -n 1
+
 include $(top_srcdir)/make/fencebuild.mk
 include $(top_srcdir)/make/fenceman.mk
-
-clean-local: clean-man
-	rm -f $(TARGET)
+include $(top_srcdir)/make/agentpycheck.mk
diff --git a/fence/agents/ilo_moonshot/fence_ilo_moonshot.py b/fence/agents/ilo_moonshot/fence_ilo_moonshot.py
new file mode 100644
index 0000000..e161ac6
--- /dev/null
+++ b/fence/agents/ilo_moonshot/fence_ilo_moonshot.py
@@ -0,0 +1,69 @@
+#!/usr/bin/python -tt
+
+import sys
+import atexit
+sys.path.append("@FENCEAGENTSLIBDIR@")
+from fencing import *
+from fencing import fail, EC_STATUS
+
+#BEGIN_VERSION_GENERATION
+RELEASE_VERSION=""
+REDHAT_COPYRIGHT=""
+BUILD_DATE=""
+#END_VERSION_GENERATION
+
+def get_power_status(conn, options):
+	conn.send_eol("show node list")
+	conn.log_expect(options["--command-prompt"], int(options["--shell-timeout"]))
+
+	nodes = {}
+	for line in conn.before.splitlines():
+		if len(line.split()) == 10:
+			nodes[line.split()[1]] = ("", line.split()[8].lower().strip())
+
+	if ["list", "monitor"].count(options["--action"]) == 1:
+		return nodes
+	else:
+		try:
+			(_, status) = nodes[options["--plug"]]
+			return status.lower()
+		except KeyError:
+			fail(EC_STATUS)
+
+def set_power_status(conn, options):
+	if options["--action"] == "on":
+		conn.send_eol("set node power on %s" % (options["--plug"]))
+	else:
+		conn.send_eol("set node power off force %s" % (options["--plug"]))
+
+	conn.log_expect(options["--command-prompt"], int(options["--power-timeout"]))
+
+	return
+
+def main():
+	device_opt = ["ipaddr", "login", "passwd", "secure", "cmd_prompt", "port"]
+
+	atexit.register(atexit_handler)
+
+	all_opt["secure"]["default"] = "1"
+	all_opt["cmd_prompt"]["default"] = ["MP>", "hpiLO->"]
+
+	options = check_input(device_opt, process_input(device_opt))
+
+	docs = {}
+	docs["shortdesc"] = "Fence agent for HP Moonshot iLO"
+	docs["longdesc"] = ""
+	docs["vendorurl"] = "http://www.hp.com"
+	show_docs(options, docs)
+
+	conn = fence_login(options)
+
+	##
+	## Fence operations
+	####
+	result = fence_action(conn, options, set_power_status, get_power_status, get_power_status)
+	fence_logout(conn, "exit")
+	sys.exit(result)
+
+if __name__ == "__main__":
+	main()
diff --git a/fence/agents/ilo_mp/Makefile.am b/fence/agents/ilo_mp/Makefile.am
index 4e8b18e..fdf265c 100644
--- a/fence/agents/ilo_mp/Makefile.am
+++ b/fence/agents/ilo_mp/Makefile.am
@@ -10,8 +10,8 @@ sbin_SCRIPTS		= $(TARGET)
 
 man_MANS		= $(TARGET).8
 
+FENCE_TEST_ARGS         = -l test -p test -a test
+
 include $(top_srcdir)/make/fencebuild.mk
 include $(top_srcdir)/make/fenceman.mk
-
-clean-local: clean-man
-	rm -f $(TARGET)
+include $(top_srcdir)/make/agentpycheck.mk
diff --git a/fence/agents/ilo_mp/fence_ilo_mp.py b/fence/agents/ilo_mp/fence_ilo_mp.py
index b1202bb..396d1a9 100644
--- a/fence/agents/ilo_mp/fence_ilo_mp.py
+++ b/fence/agents/ilo_mp/fence_ilo_mp.py
@@ -1,6 +1,7 @@
-#!/usr/bin/python
+#!/usr/bin/python -tt
 
-import sys, re, pexpect, exceptions
+import sys, re
+import atexit
 sys.path.append("@FENCEAGENTSLIBDIR@")
 from fencing import *
 
@@ -12,9 +13,9 @@ BUILD_DATE=""
 
 def get_power_status(conn, options):
 	conn.send_eol("show /system1")
-		
+
 	re_state = re.compile('EnabledState=(.*)', re.IGNORECASE)
-	conn.log_expect(options, re_state, int(options["--shell-timeout"]))
+	conn.log_expect(re_state, int(options["--shell-timeout"]))
 
 	status = conn.match.group(1).lower()
 
@@ -29,26 +30,26 @@ def set_power_status(conn, options):
 	else:
 		conn.send_eol("stop -f /system1")
 
-	conn.log_expect(options, options["--command-prompt"], int(options["--power-timeout"]))
+	conn.log_expect(options["--command-prompt"], int(options["--power-timeout"]))
 
 	return
 
 def main():
-	device_opt = [  "ipaddr", "login", "passwd", "secure", "cmd_prompt" ]
+	device_opt = ["ipaddr", "login", "passwd", "secure", "cmd_prompt", "telnet"]
 
 	atexit.register(atexit_handler)
-	
-	all_opt["cmd_prompt"]["default"] = [ "MP>", "hpiLO->" ]
+
+	all_opt["cmd_prompt"]["default"] = ["MP>", "hpiLO->"]
 	all_opt["power_wait"]["default"] = 5
-	
+
 	options = check_input(device_opt, process_input(device_opt))
-		
-	docs = { }
+
+	docs = {}
 	docs["shortdesc"] = "Fence agent for HP iLO MP"
 	docs["longdesc"] = ""
 	docs["vendorurl"] = "http://www.hp.com"
 	show_docs(options, docs)
-	
+
 	conn = fence_login(options)
 	conn.send_eol("SMCLP")
 
@@ -56,12 +57,7 @@ def main():
 	## Fence operations
 	####
 	result = fence_action(conn, options, set_power_status, get_power_status)
-
-	try:
-		conn.send_eol("exit")
-	except:
-		pass
-	
+	fence_logout(conn, "exit")
 	sys.exit(result)
 
 if __name__ == "__main__":
diff --git a/fence/agents/ipmilan/Makefile.am b/fence/agents/ilo_ssh/Makefile.am
similarity index 58%
copy from fence/agents/ipmilan/Makefile.am
copy to fence/agents/ilo_ssh/Makefile.am
index be3509e..883c306 100644
--- a/fence/agents/ipmilan/Makefile.am
+++ b/fence/agents/ilo_ssh/Makefile.am
@@ -1,8 +1,8 @@
 MAINTAINERCLEANFILES	= Makefile.in
 
-TARGET			= fence_ipmilan
+TARGET			= fence_ilo_ssh
 
-SYMTARGET		= fence_ilo3 fence_ilo4 fence_imm fence_idrac
+SYMTARGET		= fence_ilo3_ssh fence_ilo4_ssh
 
 SRC			= $(TARGET).py
 
@@ -12,11 +12,11 @@ sbin_SCRIPTS		= $(TARGET) $(SYMTARGET)
 
 man_MANS		= $(TARGET).8 $(SYMTARGET:%=%.8)
 
-$(SYMTARGET): $(TARGET)
+FENCE_TEST_ARGS         = -p test -a test -l test
+
+$(SYMTARGET) : $(TARGET)
 	cp $^ $@
 
 include $(top_srcdir)/make/fencebuild.mk
 include $(top_srcdir)/make/fenceman.mk
-
-clean-local: clean-man
-	rm -f $(TARGET) $(SYMTARGET)
+include $(top_srcdir)/make/agentpycheck.mk
diff --git a/fence/agents/ilo_ssh/fence_ilo_ssh.py b/fence/agents/ilo_ssh/fence_ilo_ssh.py
new file mode 100644
index 0000000..a510b2e
--- /dev/null
+++ b/fence/agents/ilo_ssh/fence_ilo_ssh.py
@@ -0,0 +1,75 @@
+#!/usr/bin/python -tt
+
+import sys, re
+import atexit
+sys.path.append("@FENCEAGENTSLIBDIR@")
+from fencing import *
+
+#BEGIN_VERSION_GENERATION
+RELEASE_VERSION=""
+REDHAT_COPYRIGHT=""
+BUILD_DATE=""
+#END_VERSION_GENERATION
+
+def get_power_status(conn, options):
+	conn.send_eol("show /system1")
+
+	re_state = re.compile('EnabledState=(.*)', re.IGNORECASE)
+	conn.log_expect(re_state, int(options["--shell-timeout"]))
+
+	status = conn.match.group(1).lower()
+
+	if status.startswith("enabled"):
+		return "on"
+	else:
+		return "off"
+
+def set_power_status(conn, options):
+	if options["--action"] == "on":
+		conn.send_eol("start /system1")
+	else:
+		conn.send_eol("power off hard")
+
+	conn.log_expect(options["--command-prompt"], int(options["--power-timeout"]))
+
+	return
+
+def reboot_cycle(conn, options):
+	conn.send_eol("reset hard /system1")
+	conn.log_expect(options["--command-prompt"], int(options["--power-timeout"]))
+	return
+
+def main():
+	device_opt = ["ipaddr", "login", "passwd", "secure", "cmd_prompt", "method", "telnet"]
+
+	atexit.register(atexit_handler)
+
+	all_opt["cmd_prompt"]["default"] = ["MP>", "hpiLO->"]
+	all_opt["power_wait"]["default"] = 5
+	all_opt["method"]["default"] = "onoff"
+
+	options = check_input(device_opt, process_input(device_opt))
+
+	docs = {}
+	docs["shortdesc"] = "Fence agent for HP iLO over SSH"
+	docs["longdesc"] = "fence_ilo_ssh is a fence agent that connects to iLO device. It logs into \
+device via ssh and reboot a specified outlet. "
+	docs["vendorurl"] = "http://www.hp.com"
+	docs["symlink"] = [("fence_ilo3_ssh", "Fence agent for HP iLO3 over SSH"),
+		("fence_ilo4_ssh", "Fence agent for HP iLO4 over SSH")]
+	show_docs(options, docs)
+
+	options["eol"] = "\r"
+
+	conn = fence_login(options)
+	conn.send_eol("SMCLP")
+
+	##
+	## Fence operations
+	####
+	result = fence_action(conn, options, set_power_status, get_power_status, None, reboot_cycle)
+	fence_logout(conn, "exit")
+	sys.exit(result)
+
+if __name__ == "__main__":
+	main()
diff --git a/fence/agents/intelmodular/Makefile.am b/fence/agents/intelmodular/Makefile.am
index f1e4690..837fcee 100644
--- a/fence/agents/intelmodular/Makefile.am
+++ b/fence/agents/intelmodular/Makefile.am
@@ -10,8 +10,8 @@ sbin_SCRIPTS		= $(TARGET)
 
 man_MANS		= $(TARGET).8
 
+FENCE_TEST_ARGS         = -l test -p test -a test -n 1
+
 include $(top_srcdir)/make/fencebuild.mk
 include $(top_srcdir)/make/fenceman.mk
-
-clean-local: clean-man
-	rm -f $(TARGET)
+include $(top_srcdir)/make/agentpycheck.mk
diff --git a/fence/agents/intelmodular/fence_intelmodular.py b/fence/agents/intelmodular/fence_intelmodular.py
index 192d2e3..e91ccc0 100644
--- a/fence/agents/intelmodular/fence_intelmodular.py
+++ b/fence/agents/intelmodular/fence_intelmodular.py
@@ -1,4 +1,4 @@
-#!/usr/bin/python
+#!/usr/bin/python -tt
 
 # Tested with an Intel MFSYS25 using firmware package 2.6 Should work with an
 # MFSYS35 as well.
@@ -12,9 +12,10 @@
 # Thanks Matthew Kent for original agent and testing.
 
 import sys
+import atexit
 sys.path.append("@FENCEAGENTSLIBDIR@")
 from fencing import *
-from fencing_snmp import *
+from fencing_snmp import FencingSnmp
 
 #BEGIN_VERSION_GENERATION
 RELEASE_VERSION="Intel Modular SNMP fence agent"
@@ -38,11 +39,12 @@ STATUS_SET_OFF = 3
 ### FUNCTIONS ###
 
 def get_power_status(conn, options):
-	(oid, status) = conn.get("%s.%s"% (STATUSES_OID, options["--plug"]))
-	return (status==str(STATUS_UP) and "on" or "off")
+	(_, status) = conn.get("%s.%s"% (STATUSES_OID, options["--plug"]))
+	return status == str(STATUS_UP) and "on" or "off"
 
 def set_power_status(conn, options):
-	conn.set("%s.%s"%(STATUSES_OID, options["--plug"]), (options["--action"]=="on" and STATUS_SET_ON or STATUS_SET_OFF))
+	conn.set("%s.%s" % (STATUSES_OID, options["--plug"]),
+			(options["--action"] == "on" and STATUS_SET_ON or STATUS_SET_OFF))
 
 def get_outlets_status(conn, options):
 	result = {}
@@ -53,7 +55,7 @@ def get_outlets_status(conn, options):
 		port_num = x[0].split('.')[-1]
 
 		port_alias = ""
-		port_status = (x[1]==str(STATUS_UP) and "on" or "off")
+		port_status = (x[1] == str(STATUS_UP) and "on" or "off")
 
 		result[port_num] = (port_alias, port_status)
 
@@ -61,16 +63,14 @@ def get_outlets_status(conn, options):
 
 # Main agent method
 def main():
-	device_opt = [ "ipaddr", "login", "passwd", "no_login", "no_password",
-		       "port", "snmp_version", "community" ]
+	device_opt = ["ipaddr", "login", "passwd", "no_login", "no_password",
+		       "port", "snmp_version", "snmp"]
 
 	atexit.register(atexit_handler)
 
-	snmp_define_defaults ()
-
 	options = check_input(device_opt, process_input(device_opt))
 
-	docs = { }
+	docs = {}
 	docs["shortdesc"] = "Fence agent for Intel Modular"
 	docs["longdesc"] = "fence_intelmodular is an I/O Fencing agent \
 which can be used with Intel Modular device (tested on Intel MFSYS25, should \
@@ -85,7 +85,7 @@ for command line and snmp_version option for your cluster.conf."
 
 	# Operate the fencing device
 	result = fence_action(FencingSnmp(options), options, set_power_status, get_power_status, get_outlets_status)
-	
+
 	sys.exit(result)
 
 if __name__ == "__main__":
diff --git a/fence/agents/ipdu/Makefile.am b/fence/agents/ipdu/Makefile.am
index fb02cc8..8b16284 100644
--- a/fence/agents/ipdu/Makefile.am
+++ b/fence/agents/ipdu/Makefile.am
@@ -10,8 +10,8 @@ sbin_SCRIPTS		= $(TARGET)
 
 man_MANS		= $(TARGET).8
 
+FENCE_TEST_ARGS         = -l test -p test -a test -n 1
+
 include $(top_srcdir)/make/fencebuild.mk
 include $(top_srcdir)/make/fenceman.mk
-
-clean-local: clean-man
-	rm -f $(TARGET)
+include $(top_srcdir)/make/agentpycheck.mk
diff --git a/fence/agents/ipdu/fence_ipdu.py b/fence/agents/ipdu/fence_ipdu.py
index 7f08656..642dc79 100644
--- a/fence/agents/ipdu/fence_ipdu.py
+++ b/fence/agents/ipdu/fence_ipdu.py
@@ -1,4 +1,4 @@
-#!/usr/bin/python
+#!/usr/bin/python -tt
 
 # The Following agent has been tested on:
 #   IBM iPDU model 46M4002
@@ -6,9 +6,12 @@
 #
 
 import sys
+import atexit
+import logging
 sys.path.append("/usr/share/fence")
 from fencing import *
-from fencing_snmp import *
+from fencing import fail_usage
+from fencing_snmp import FencingSnmp
 
 #BEGIN_VERSION_GENERATION
 RELEASE_VERSION="IBM iPDU SNMP fence agent"
@@ -30,7 +33,7 @@ port_id = None
 switch_id = None
 
 # Classes describing Device params
-class IBMiPDU:
+class IBMiPDU(object):
 	# iPDU
 	status_oid =       '.1.3.6.1.4.1.2.6.223.8.2.2.1.11.%d'
 	control_oid =      '.1.3.6.1.4.1.2.6.223.8.2.2.1.11.%d'
@@ -52,62 +55,62 @@ def ipdu_set_device(conn, options):
 	# First resolve type of PDU device
 	pdu_type = conn.walk(OID_SYS_OBJECT_ID)
 
-	if (not ((len(pdu_type)==1) and (agents_dir.has_key(pdu_type[0][1])))):
+	if not ((len(pdu_type) == 1) and (agents_dir.has_key(pdu_type[0][1]))):
 		pdu_type = [[None, None]]
 
 	device = agents_dir[pdu_type[0][1]]
 
-	conn.log_command("Trying %s"%(device.ident_str))
+	logging.debug("Trying %s"%(device.ident_str))
 
 def ipdu_resolv_port_id(conn, options):
 	global port_id, switch_id
 
-	if (device==None):
+	if device == None:
 		ipdu_set_device(conn, options)
 
 	# Now we resolv port_id/switch_id
-	if ((options["--plug"].isdigit()) and ((not device.has_switches) or (options["--switch"].isdigit()))):
+	if options["--plug"].isdigit() and ((not device.has_switches) or (options["--switch"].isdigit())):
 		port_id = int(options["--plug"])
 
-		if (device.has_switches):
+		if device.has_switches:
 			switch_id = int(options["--switch"])
 	else:
 		table = conn.walk(device.outlet_table_oid, 30)
 
 		for x in table:
-			if (x[1].strip('"')==options["--plug"]):
+			if x[1].strip('"') == options["--plug"]:
 				t = x[0].split('.')
-				if (device.has_switches):
+				if device.has_switches:
 					port_id = int(t[len(t)-1])
 					switch_id = int(t[len(t)-3])
 				else:
 					port_id = int(t[len(t)-1])
 
-	if (port_id==None):
+	if port_id == None:
 		fail_usage("Can't find port with name %s!"%(options["--plug"]))
 
 def get_power_status(conn, options):
-	if (port_id==None):
+	if port_id == None:
 		ipdu_resolv_port_id(conn, options)
 
 	oid = ((device.has_switches) and device.status_oid%(switch_id, port_id) or device.status_oid%(port_id))
 
 	(oid, status) = conn.get(oid)
-	return (status==str(device.state_on) and "on" or "off")
+	return status == str(device.state_on) and "on" or "off"
 
 def set_power_status(conn, options):
-	if (port_id==None):
+	if port_id == None:
 		ipdu_resolv_port_id(conn, options)
 
 	oid = ((device.has_switches) and device.control_oid%(switch_id, port_id) or device.control_oid%(port_id))
 
-	conn.set(oid,(options["--action"]=="on" and device.turn_on or device.turn_off))
+	conn.set(oid, (options["--action"] == "on" and device.turn_on or device.turn_off))
 
 
 def get_outlets_status(conn, options):
 	result = {}
 
-	if (device == None):
+	if device == None:
 		ipdu_set_device(conn, options)
 
 	res_ports = conn.walk(device.outlet_table_oid, 30)
@@ -125,12 +128,13 @@ def get_outlets_status(conn, options):
 
 # Main agent method
 def main():
-	device_opt = [ "ipaddr", "login", "passwd", "no_login", "no_password", \
-		       "port", "snmp_version", "community" ]
+	global device
+
+	device_opt = ["ipaddr", "login", "passwd", "no_login", "no_password", \
+		       "port", "snmp_version", "snmp"]
 
 	atexit.register(atexit_handler)
 
-	snmp_define_defaults ()
 	all_opt["snmp_version"]["default"] = "3"
 	all_opt["community"]["default"] = "private"
 	all_opt["switch"]["default"] = "1"
@@ -138,7 +142,7 @@ def main():
 
 	options = check_input(device_opt, process_input(device_opt))
 
-	docs = { }
+	docs = {}
 	docs["shortdesc"] = "Fence agent for iPDU over SNMP"
 	docs["longdesc"] = "fence_ipdu is an I/O Fencing agent \
 which can be used with the IBM iPDU network power switch. It logs \
diff --git a/fence/agents/ipmilan/Makefile.am b/fence/agents/ipmilan/Makefile.am
index be3509e..fba2198 100644
--- a/fence/agents/ipmilan/Makefile.am
+++ b/fence/agents/ipmilan/Makefile.am
@@ -12,11 +12,11 @@ sbin_SCRIPTS		= $(TARGET) $(SYMTARGET)
 
 man_MANS		= $(TARGET).8 $(SYMTARGET:%=%.8)
 
+FENCE_TEST_ARGS         = -l test -p test -a test
+
 $(SYMTARGET): $(TARGET)
 	cp $^ $@
 
 include $(top_srcdir)/make/fencebuild.mk
 include $(top_srcdir)/make/fenceman.mk
-
-clean-local: clean-man
-	rm -f $(TARGET) $(SYMTARGET)
+include $(top_srcdir)/make/agentpycheck.mk
diff --git a/fence/agents/ipmilan/fence_ipmilan.py b/fence/agents/ipmilan/fence_ipmilan.py
index de42524..a396970 100644
--- a/fence/agents/ipmilan/fence_ipmilan.py
+++ b/fence/agents/ipmilan/fence_ipmilan.py
@@ -1,9 +1,11 @@
-#!/usr/bin/python
+#!/usr/bin/python -tt
 
-import sys, shlex, stat, subprocess, re, os
+import sys, re, os
+import atexit
 from pipes import quote
 sys.path.append("@FENCEAGENTSLIBDIR@")
 from fencing import *
+from fencing import fail_usage, is_executable, run_command, run_delay
 
 #BEGIN_VERSION_GENERATION
 RELEASE_VERSION=""
@@ -12,189 +14,149 @@ BUILD_DATE=""
 #END_VERSION_GENERATION
 
 def get_power_status(_, options):
-
-    cmd = create_command(options, "status")
-
-    if options["log"] >= LOG_MODE_VERBOSE:
-        options["debug_fh"].write("executing: " + cmd + "\n")
-
-    try:
-        process = subprocess.Popen(shlex.split(cmd), stdout=subprocess.PIPE, stderr=subprocess.PIPE)
-    except OSError:
-        fail_usage("Ipmitool not found or not accessible")
-
-    process.wait()
-
-    out = process.communicate()
-    process.stdout.close()
-    options["debug_fh"].write(str(out) + "\n")
-
-    match = re.search('[Cc]hassis [Pp]ower is [\\s]*([a-zA-Z]{2,3})', str(out))
-    status = match.group(1) if match else None
-
-    return status
+	output = run_command(options, create_command(options, "status"))
+	match = re.search('[Cc]hassis [Pp]ower is [\\s]*([a-zA-Z]{2,3})', str(output))
+	status = match.group(1) if match else None
+	return status
 
 def set_power_status(_, options):
-
-    cmd = create_command(options, options["--action"])
-
-    if options["log"] >= LOG_MODE_VERBOSE:
-        options["debug_fh"].write("executing: " + cmd + "\n")
-
-    try:
-        process = subprocess.Popen(shlex.split(cmd), stdout=options["debug_fh"], stderr=options["debug_fh"])
-    except OSError:
-        fail_usage("Ipmitool not found or not accessible")
-
-    process.wait()
-
-    return
+	run_command(options, create_command(options, options["--action"]))
+	return
 
 def reboot_cycle(_, options):
-    cmd = create_command(options, "cycle")
-
-    if options["log"] >= LOG_MODE_VERBOSE:
-        options["debug_fh"].write("executing: " + cmd + "\n")
-
-    try:
-        process = subprocess.Popen(shlex.split(cmd), stdout=subprocess.PIPE, stderr=subprocess.PIPE)
-    except OSError:
-        fail_usage("Ipmitool not found or not accessible")
-
-    process.wait()
-
-    out = process.communicate()
-    process.stdout.close()
-    options["debug_fh"].write(str(out) + "\n")
-
-    return bool(re.search('chassis power control: cycle', str(out).lower()))
+	output = run_command(options, create_command(options, "cycle"))
+	return bool(re.search('chassis power control: cycle', str(output).lower()))
 
 def create_command(options, action):
-    cmd = options["--ipmitool-path"]
+	cmd = options["--ipmitool-path"]
 
-    # --lanplus / -L
-    if options.has_key("--lanplus") and options["--lanplus"] in ["", "1"]:
-        cmd += " -I lanplus"
-    else:
-        cmd += " -I lan"
-    # --ip / -a
-    cmd += " -H " + options["--ip"]
+	# --lanplus / -L
+	if options.has_key("--lanplus") and options["--lanplus"] in ["", "1"]:
+		cmd += " -I lanplus"
+	else:
+		cmd += " -I lan"
+	# --ip / -a
+	cmd += " -H " + options["--ip"]
 
-    # --username / -l
-    if options.has_key("--username") and len(options["--username"]) != 0:
-        cmd += " -U " + quote(options["--username"])
+	# --username / -l
+	if options.has_key("--username") and len(options["--username"]) != 0:
+		cmd += " -U " + quote(options["--username"])
 
-    # --auth / -A
-    if options.has_key("--auth"):
-        cmd += " -A " + options["--auth"]
+	# --auth / -A
+	if options.has_key("--auth"):
+		cmd += " -A " + options["--auth"]
 
-    # --password / -p
-    if options.has_key("--password"):
-        cmd += " -P " + quote(options["--password"])
+	# --password / -p
+	if options.has_key("--password"):
+		cmd += " -P " + quote(options["--password"])
+	else:
+		cmd += " -P ''"
 
-    # --cipher / -C
-    cmd += " -C " + options["--cipher"]
+	# --cipher / -C
+	if "--cipher" in options:
+		cmd += " -C " + options["--cipher"]
 
-    # --port / -n
-    if options.has_key("--ipport"):
-        cmd += " -p " + options["--ipport"]
+	# --port / -n
+	if options.has_key("--ipport"):
+		cmd += " -p " + options["--ipport"]
 
-    if options.has_key("--privlvl"):
-        cmd += " -L " + options["--privlvl"]
+	if options.has_key("--privlvl"):
+		cmd += " -L " + options["--privlvl"]
 
-    # --action / -o
-    cmd += " chassis power " + action
+	# --action / -o
+	cmd += " chassis power " + action
 
-     # --use-sudo / -d
-    if options.has_key("--use-sudo"):
-        cmd = SUDO_PATH + " " + cmd
+	# --use-sudo / -d
+	if options.has_key("--use-sudo"):
+		cmd = options["--sudo-path"] + " " + cmd
 
-    return cmd
+	return cmd
 
 def define_new_opts():
-    all_opt["lanplus"] = {
-        "getopt" : "P",
-        "longopt" : "lanplus",
-        "help" : "-P, --lanplus                  Use Lanplus to improve security of connection",
-        "required" : "0",
-        "default" : "0",
-        "shortdesc" : "Use Lanplus to improve security of connection",
-        "order": 1
-        }
-    all_opt["auth"] = {
-        "getopt" : "A:",
-        "longopt" : "auth",
-        "help" : "-A, --auth=[auth]              IPMI Lan Auth type (md5|password|none)",
-        "required" : "0",
-        "shortdesc" : "IPMI Lan Auth type.",
-        "choices" : ["md5", "password", "none"],
-        "order": 1
-        }
-    all_opt["cipher"] = {
-        "getopt" : "C:",
-        "longopt" : "cipher",
-        "help" : "-C, --cipher=[cipher]          Ciphersuite to use (same as ipmitool -C parameter)",
-        "required" : "0",
-        "shortdesc" : "Ciphersuite to use (same as ipmitool -C parameter)",
-        "default" : "0",
-        "order": 1
-        }
-    all_opt["privlvl"] = {
-        "getopt" : "L:",
-        "longopt" : "privlvl",
-        "help" : "-L, --privlvl=[level]          Privilege level on IPMI device (callback|user|operator|administrator)",
-        "required" : "0",
-        "shortdesc" : "Privilege level on IPMI device",
-        "default" : "administrator",
-        "choices" : ["callback", "user", "operator", "administrator"],
-        "order": 1
-        }
-    all_opt["ipmitool_path"] = {
-        "getopt" : "i:",
-        "longopt" : "ipmitool-path",
-        "help" : "--ipmitool-path=[path]         Path to ipmitool binary",
-        "required" : "0",
-        "shortdesc" : "Path to ipmitool binary",
-        "default" : "@IPMITOOL_PATH@",
-        "order": 200
-        }
+	all_opt["lanplus"] = {
+		"getopt" : "P",
+		"longopt" : "lanplus",
+		"help" : "-P, --lanplus                  Use Lanplus to improve security of connection",
+		"required" : "0",
+		"default" : "0",
+		"shortdesc" : "Use Lanplus to improve security of connection",
+		"order": 1
+	}
+	all_opt["auth"] = {
+		"getopt" : "A:",
+		"longopt" : "auth",
+		"help" : "-A, --auth=[auth]              IPMI Lan Auth type (md5|password|none)",
+		"required" : "0",
+		"shortdesc" : "IPMI Lan Auth type.",
+		"choices" : ["md5", "password", "none"],
+		"order": 1
+	}
+	all_opt["cipher"] = {
+		"getopt" : "C:",
+		"longopt" : "cipher",
+		"help" : "-C, --cipher=[cipher]          Ciphersuite to use (same as ipmitool -C parameter)",
+		"required" : "0",
+		"shortdesc" : "Ciphersuite to use (same as ipmitool -C parameter)",
+		"order": 1
+	}
+	all_opt["privlvl"] = {
+		"getopt" : "L:",
+		"longopt" : "privlvl",
+		"help" : "-L, --privlvl=[level]          "
+				"Privilege level on IPMI device (callback|user|operator|administrator)",
+		"required" : "0",
+		"shortdesc" : "Privilege level on IPMI device",
+		"default" : "administrator",
+		"choices" : ["callback", "user", "operator", "administrator"],
+		"order": 1
+	}
+	all_opt["ipmitool_path"] = {
+		"getopt" : ":",
+		"longopt" : "ipmitool-path",
+		"help" : "--ipmitool-path=[path]         Path to ipmitool binary",
+		"required" : "0",
+		"shortdesc" : "Path to ipmitool binary",
+		"default" : "@IPMITOOL_PATH@",
+		"order": 200
+	}
 
 def main():
+	atexit.register(atexit_handler)
 
-    atexit.register(atexit_handler)
+	device_opt = ["ipaddr", "login", "no_login", "no_password", "passwd",
+		"lanplus", "auth", "cipher", "privlvl", "sudo", "ipmitool_path", "method"]
+	define_new_opts()
 
-    device_opt = ["ipaddr", "login", "no_login", "no_password", "passwd",
-                  "lanplus", "auth", "cipher", "privlvl", "sudo", "ipmitool_path", "method"]
-    define_new_opts()
+	if os.path.basename(sys.argv[0]) == "fence_ilo3":
+		all_opt["power_wait"]["default"] = "4"
+		all_opt["method"]["default"] = "cycle"
+		all_opt["lanplus"]["default"] = "1"
+	elif os.path.basename(sys.argv[0]) == "fence_ilo4":
+		all_opt["lanplus"]["default"] = "1"
 
-    if os.path.basename(sys.argv[0]) == "fence_ilo3":
-        all_opt["power_wait"]["default"] = "4"
-        all_opt["method"]["default"] = "cycle"
-        all_opt["lanplus"]["default"] = "1"
-    elif os.path.basename(sys.argv[0]) == "fence_ilo4":
-        all_opt["lanplus"]["default"] = "1"
+	all_opt["ipport"]["default"] = "623"
 
-    all_opt["ipport"]["default"] = "623"
+	options = check_input(device_opt, process_input(device_opt))
 
-    options = check_input(device_opt, process_input(device_opt))
-
-    docs = { }
-    docs["shortdesc"] = "Fence agent for IPMI"
-    docs["longdesc"] = "fence_ipmilan is an I/O Fencing agent\
+	docs = {}
+	docs["shortdesc"] = "Fence agent for IPMI"
+	docs["longdesc"] = "fence_ipmilan is an I/O Fencing agent\
 which can be used with machines controlled by IPMI.\
 This agent calls support software ipmitool (http://ipmitool.sf.net/)."
-    docs["vendorurl"] = ""
-    docs["symlink"] = [("fence_ilo3", "Fence agent for HP iLO3"),
-                       ("fence_ilo4", "Fence agent for HP iLO4"),
-                       ("fence_imm", "Fence agent for IBM Integrated Management Module"),
-                       ("fence_idrac", "Fence agent for Dell iDRAC")]
-    show_docs(options, docs)
+	docs["vendorurl"] = ""
+	docs["symlink"] = [("fence_ilo3", "Fence agent for HP iLO3"),
+		("fence_ilo4", "Fence agent for HP iLO4"),
+		("fence_imm", "Fence agent for IBM Integrated Management Module"),
+		("fence_idrac", "Fence agent for Dell iDRAC")]
+	show_docs(options, docs)
+
+	run_delay(options)
 
-    if not is_executable(options["--ipmitool-path"]):
-        fail_usage("Ipmitool not found or not accessible")
+	if not is_executable(options["--ipmitool-path"]):
+		fail_usage("Ipmitool not found or not accessible")
 
-    result = fence_action(None, options, set_power_status, get_power_status, None, reboot_cycle)
-    sys.exit(result)
+	result = fence_action(None, options, set_power_status, get_power_status, None, reboot_cycle)
+	sys.exit(result)
 
 if __name__ == "__main__":
-    main()
+	main()
diff --git a/fence/agents/kdump/Makefile.am b/fence/agents/kdump/Makefile.am
index 26e452c..2195f64 100644
--- a/fence/agents/kdump/Makefile.am
+++ b/fence/agents/kdump/Makefile.am
@@ -12,3 +12,9 @@ fence_kdump_send_SOURCES	= fence_kdump_send.c
 fence_kdump_send_CFLAGS		= -D_GNU_SOURCE
 
 dist_man_MANS			= fence_kdump.8 fence_kdump_send.8
+
+FENCE_TEST_ARGS			= -n test
+
+include $(top_srcdir)/make/agentccheck.mk
+
+check: xml-check.fence_kdump
diff --git a/fence/agents/kdump/fence_kdump.c b/fence/agents/kdump/fence_kdump.c
index cae9842..781df64 100644
--- a/fence/agents/kdump/fence_kdump.c
+++ b/fence/agents/kdump/fence_kdump.c
@@ -114,6 +114,35 @@ out:
 }
 
 static int
+do_action_monitor (void)
+{
+    const char cmdline_path[] = "/proc/cmdline";
+    FILE *procFile;
+    size_t sz = 0;
+    char *lines = NULL;
+    int result = 1;
+
+    procFile = fopen(cmdline_path, "r");
+
+    if (procFile == NULL) {
+        log_error (0, "Unable to open file %s (%s)\n", cmdline_path, strerror (errno));
+        return 1;
+    }
+
+    while (!feof (procFile)) {
+        ssize_t rv = getline (&lines, &sz, procFile);
+        if ((rv != -1) && (strstr(lines, "crashkernel=") != NULL)) {
+            result = 0;
+        }
+    }
+
+    free (lines);
+    fclose (procFile);
+
+    return result;
+}
+
+static int
 do_action_off (const fence_kdump_opts_t *opts)
 {
     int error;
@@ -242,6 +271,7 @@ do_action_metadata (const char *self)
 
     fprintf (stdout, "<actions>\n");
     fprintf (stdout, "\t<action name=\"off\" />\n");
+    fprintf (stdout, "\t<action name=\"monitor\" />\n");
     fprintf (stdout, "\t<action name=\"metadata\" />\n");
     fprintf (stdout, "</actions>\n");
 
@@ -264,7 +294,7 @@ print_usage (const char *self)
     fprintf (stdout, "%s\n",
              "  -f, --family=FAMILY          Network family: ([auto], ipv4, ipv6)");
     fprintf (stdout, "%s\n",
-             "  -o, --action=ACTION          Fencing action: ([off], metadata)");
+             "  -o, --action=ACTION          Fencing action: ([off], monitor, metadata)");
     fprintf (stdout, "%s\n",
              "  -t, --timeout=TIMEOUT        Timeout in seconds (default: 60)");
     fprintf (stdout, "%s\n",
@@ -501,6 +531,9 @@ main (int argc, char **argv)
     case FENCE_KDUMP_ACTION_METADATA:
         error = do_action_metadata (argv[0]);
         break;
+    case FENCE_KDUMP_ACTION_MONITOR:
+        error = do_action_monitor ();
+        break;
     default:
         break;
     }
diff --git a/fence/agents/kdump/options.h b/fence/agents/kdump/options.h
index 10fa2a2..22731d7 100644
--- a/fence/agents/kdump/options.h
+++ b/fence/agents/kdump/options.h
@@ -189,6 +189,8 @@ set_option_action (fence_kdump_opts_t *opts, const char *arg)
         opts->action = FENCE_KDUMP_ACTION_OFF;
     } else if (!strcasecmp (arg, "metadata")) {
         opts->action = FENCE_KDUMP_ACTION_METADATA;
+    } else if (!strcasecmp (arg, "monitor")) {
+        opts->action = FENCE_KDUMP_ACTION_MONITOR;
     } else {
         fprintf (stderr, "[error]: unsupported action '%s'\n", arg);
         exit (1);
diff --git a/fence/agents/ldom/Makefile.am b/fence/agents/ldom/Makefile.am
index a229934..8a58536 100644
--- a/fence/agents/ldom/Makefile.am
+++ b/fence/agents/ldom/Makefile.am
@@ -10,8 +10,8 @@ sbin_SCRIPTS		= $(TARGET)
 
 man_MANS		= $(TARGET).8
 
+FENCE_TEST_ARGS         = -l test -p test -a test -n 1
+
 include $(top_srcdir)/make/fencebuild.mk
 include $(top_srcdir)/make/fenceman.mk
-
-clean-local: clean-man
-	rm -f $(TARGET)
+include $(top_srcdir)/make/agentpycheck.mk
diff --git a/fence/agents/ldom/fence_ldom.py b/fence/agents/ldom/fence_ldom.py
index 722bfda..27a1a4a 100644
--- a/fence/agents/ldom/fence_ldom.py
+++ b/fence/agents/ldom/fence_ldom.py
@@ -1,15 +1,17 @@
-#!/usr/bin/python
+#!/usr/bin/python -tt
 
 ##
 ## The Following Agent Has Been Tested On - LDOM 1.0.3
-## The interface is backward compatible so it will work 
+## The interface is backward compatible so it will work
 ## with 1.0, 1.0.1 and .2 too.
-## 
+##
 #####
 
 import sys, re, pexpect, exceptions
+import atexit
 sys.path.append("@FENCEAGENTSLIBDIR@")
 from fencing import *
+from fencing import fail_usage
 
 #BEGIN_VERSION_GENERATION
 RELEASE_VERSION="Logical Domains (LDoms) fence Agent"
@@ -17,42 +19,41 @@ REDHAT_COPYRIGHT=""
 BUILD_DATE=""
 #END_VERSION_GENERATION
 
-COMMAND_PROMPT_REG = "\[PEXPECT\]$"
+COMMAND_PROMPT_REG = r"\[PEXPECT\]$"
 COMMAND_PROMPT_NEW = "[PEXPECT]"
 
 # Start comunicating after login. Prepare good environment.
 def start_communication(conn, options):
-	conn.send_eol ("PS1='"+COMMAND_PROMPT_NEW+"'")
+	conn.send_eol("PS1='" + COMMAND_PROMPT_NEW + "'")
 	res = conn.expect([pexpect.TIMEOUT, COMMAND_PROMPT_REG], int(options["--shell-timeout"]))
 	if res == 0:
 		#CSH stuff
-		conn.send_eol("set prompt='"+COMMAND_PROMPT_NEW+"'")
-		conn.log_expect(options, COMMAND_PROMPT_REG, int(options["--shell-timeout"]))
-	
+		conn.send_eol("set prompt='" + COMMAND_PROMPT_NEW + "'")
+		conn.log_expect(COMMAND_PROMPT_REG, int(options["--shell-timeout"]))
 
 def get_power_status(conn, options):
 	start_communication(conn, options)
-		
+
 	conn.send_eol("ldm ls")
-		    
-	conn.log_expect(options, COMMAND_PROMPT_REG, int(options["--shell-timeout"]))
+
+	conn.log_expect(COMMAND_PROMPT_REG, int(options["--shell-timeout"]))
 
 	result = {}
 
 	#This is status of mini finite automata. 0 = we didn't found NAME and STATE, 1 = we did
 	fa_status = 0
-		
+
 	for line in conn.before.splitlines():
-		domain = re.search("^(\S+)\s+(\S+)\s+.*$", line)
+		domain = re.search(r"^(\S+)\s+(\S+)\s+.*$", line)
 
-		if (domain!=None):
-			if ((fa_status==0) and (domain.group(1)=="NAME") and (domain.group(2)=="STATE")):
+		if domain != None:
+			if fa_status == 0 and domain.group(1) == "NAME" and domain.group(2) == "STATE":
 				fa_status = 1
-			elif (fa_status==1):
-				result[domain.group(1)] = ("", (domain.group(2).lower()=="bound" and "off" or "on"))
+			elif fa_status == 1:
+				result[domain.group(1)] = ("", (domain.group(2).lower() == "bound" and "off" or "on"))
 
-	if (not (options["--action"] in ['monitor','list'])):
-		if (not (options["--plug"] in result)):
+	if not options["--action"] in ['monitor', 'list']:
+		if not options["--plug"] in result:
 			fail_usage("Failed: You have to enter existing logical domain!")
 		else:
 			return result[options["--plug"]][1]
@@ -61,24 +62,24 @@ def get_power_status(conn, options):
 
 def set_power_status(conn, options):
 	start_communication(conn, options)
-         	
-	cmd_line = "ldm "+(options["--action"]=="on" and "start" or "stop -f")+" \""+options["--plug"]+"\""
-            	
+
+	cmd_line = "ldm "+ (options["--action"] == "on" and "start" or "stop -f") + " \"" + options["--plug"] + "\""
+
 	conn.send_eol(cmd_line)
-		    
-	conn.log_expect(options, COMMAND_PROMPT_REG, int(options["--power-timeout"]))
-		
+
+	conn.log_expect(COMMAND_PROMPT_REG, int(options["--power-timeout"]))
+
 def main():
-	device_opt = [ "ipaddr", "login", "passwd", "cmd_prompt", "secure", "port" ]
+	device_opt = ["ipaddr", "login", "passwd", "cmd_prompt", "secure", "port"]
 
 	atexit.register(atexit_handler)
 
 	all_opt["secure"]["default"] = "1"
-	all_opt["cmd_prompt"]["default"] = [ "\ $" ]
+	all_opt["cmd_prompt"]["default"] = [r"\ $"]
 
 	options = check_input(device_opt, process_input(device_opt))
 
-	docs = { }
+	docs = {}
 	docs["shortdesc"] = "Fence agent for Sun LDOM"
 	docs["longdesc"] = "fence_ldom is an I/O Fencing agent \
 which can be used with LDoms virtual machines. This agent works \
@@ -100,19 +101,8 @@ root. Than prompt is $, so again, you must use parameter -c."
 	####
 	conn = fence_login(options)
 	result = fence_action(conn, options, set_power_status, get_power_status, get_power_status)
-
-	##
-	## Logout from system
-	######
-	try:
-		conn.send_eol("logout")
-		conn.close()
-	except exceptions.OSError:
-		pass
-	except pexpect.ExceptionPexpect:
-		pass
-
-	sys.exit(result)		
+	fence_logout(conn, "logout")
+	sys.exit(result)
 
 if __name__ == "__main__":
 	main()
diff --git a/fence/agents/lib/Makefile.am b/fence/agents/lib/Makefile.am
index 4cf4b9f..749de19 100644
--- a/fence/agents/lib/Makefile.am
+++ b/fence/agents/lib/Makefile.am
@@ -8,7 +8,7 @@ endif
 
 SRC			= fencing.py.py fencing_snmp.py.py XenAPI.py.py check_used_options.py
 
-XSL			= fence2man.xsl fence2rng.xsl
+XSL			= fence2man.xsl fence2rng.xsl fence2wiki.xsl
 
 FASRNG			= fence.rng.head fence.rng.tail metadata.rng
 
@@ -24,5 +24,4 @@ rng_DATA		= $(XSL) $(FASRNG)
 
 include $(top_srcdir)/make/fencebuild.mk
 
-clean-local:
-	rm -f $(TARGET) *.pyc
+clean-man:
diff --git a/fence/agents/lib/XenAPI.py.py b/fence/agents/lib/XenAPI.py.py
index ce905fd..b91efda 100644
--- a/fence/agents/lib/XenAPI.py.py
+++ b/fence/agents/lib/XenAPI.py.py
@@ -48,8 +48,9 @@ import gettext
 import xmlrpclib
 import httplib
 import socket
+import logging
 
-translation = gettext.translation('xen-xm', fallback = True)
+translation = gettext.translation('xen-xm', fallback=True)
 
 class Failure(Exception):
 	def __init__(self, details):
@@ -72,8 +73,7 @@ class Failure(Exception):
 			return "Message database broken: %s.\nXen-API failure: %s" % \
 				   (exn, str(self.details))
 		except Exception, exn:
-			import sys
-			print >> sys.stderr, exn
+			logging.error("%s\n", str(exn))
 			return "Xen-API failure: %s" % str(self.details)
 
 	def _details_map(self):
@@ -81,7 +81,7 @@ class Failure(Exception):
 					 for i in range(len(self.details))])
 
 
-_RECONNECT_AND_RETRY = (lambda _ : ())
+_RECONNECT_AND_RETRY = (lambda _: ())
 
 class UDSHTTPConnection(httplib.HTTPConnection):
 	""" Stupid hacked up HTTPConnection subclass to allow HTTP over Unix domain
diff --git a/fence/agents/lib/check_used_options.py b/fence/agents/lib/check_used_options.py
index 2d75756..0eb19e3 100755
--- a/fence/agents/lib/check_used_options.py
+++ b/fence/agents/lib/check_used_options.py
@@ -1,6 +1,6 @@
-#!/usr/bin/python
+#!/usr/bin/python -tt
 
-## Check if fence agent uses only options["--??"] which are defined in fencing library or 
+## Check if fence agent uses only options["--??"] which are defined in fencing library or
 ## fence agent itself
 ##
 ## Usage: ./check_used_options.py fence-agent (e.g. lpar/fence_lpar.py)
@@ -13,7 +13,7 @@ from fencing import all_opt
 def main():
 	agent = sys.argv[1]
 
-	available = { }
+	available = {}
 
 	## all_opt from fencing library are imported
 	for k in all_opt.keys():
@@ -25,8 +25,8 @@ def main():
 
 	## all_opt defined in fence agent are found
 	agent_file = open(agent)
-	opt_re = re.compile("\s*all_opt\[\"([^\"]*)\"\] = {")
-	opt_longopt_re = re.compile("\s*\"longopt\" : \"([^\"]*)\"")
+	opt_re = re.compile(r"\s*all_opt\[\"([^\"]*)\"\] = {")
+	opt_longopt_re = re.compile(r"\s*\"longopt\" : \"([^\"]*)\"")
 
 	in_opt = False
 	for line in agent_file:
@@ -38,21 +38,21 @@ def main():
 
 	## check if all options are defined
 	agent_file = open(agent)
-	option_use_re = re.compile("options\[\"(--[^\"]*)\"\]")
-	option_has_re = re.compile("options.has_key\(\"(--[^\"]*)\"\)")
+	option_use_re = re.compile(r"options\[\"(-[^\"]*)\"\]")
+	option_has_re = re.compile(r"options.has_key\(\"(-[^\"]*)\"\)")
 
 	counter = 0
 	without_errors = True
 	for line in agent_file:
 		counter += 1
 
-		for x in option_use_re.findall(line):
-			if not available.has_key(x):
+		for option in option_use_re.findall(line):
+			if not available.has_key(option):
 				print "ERROR on line %d in %s: option %s is not defined" % (counter, agent, option_use_re.search(line).group(1))
 				without_errors = False
 
-		for x in option_has_re.findall(line):
-			if not available.has_key(x):
+		for option in option_has_re.findall(line):
+			if not available.has_key(option):
 				print "ERROR on line %d in %s: option %s is not defined" % (counter, agent, option_has_re.search(line).group(1))
 				without_errors = False
 
diff --git a/fence/agents/lib/fence2rng.xsl b/fence/agents/lib/fence2rng.xsl
index 432bc89..f6d465e 100644
--- a/fence/agents/lib/fence2rng.xsl
+++ b/fence/agents/lib/fence2rng.xsl
@@ -124,6 +124,12 @@
         <xsl:value-of select="$NL"/>
 
         <xsl:for-each select="parameters/parameter">
+            <xsl:variable name="escapeddesc">
+                <xsl:call-template name="escape_quot">
+                    <xsl:with-param name="replace" select="shortdesc"/>
+                </xsl:call-template>
+        </xsl:variable>
+
             <!-- optional (start) -->
             <xsl:call-template name="tag-start">
                 <xsl:with-param name="name" select="'optional'"/>
@@ -136,7 +142,7 @@
                 <xsl:with-param name="name" select="'attribute'"/>
                 <xsl:with-param name="attrs" select="concat(
                     'name=',            $Q, @name,                      $Q, $SP,
-                    'rha:description=', $Q, normalize-space(shortdesc), $Q, $SP)"/>
+                    'rha:description=', $Q, normalize-space($escapeddesc), $Q, $SP)"/>
                 <xsl:with-param name="indent" select="concat($indent, $indent)"/>
             </xsl:call-template>
             <xsl:value-of select="$NL"/>
@@ -158,4 +164,21 @@
     <xsl:value-of select="$NL"/>
 </xsl:template>
 
+<xsl:template name="escape_quot">
+    <xsl:param name="replace"/>
+    <xsl:choose>
+        <xsl:when test="contains($replace,'"')">
+            <xsl:value-of select="substring-before($replace,'"')"/>
+            <!-- escape quot-->
+            <xsl:text>&quot;</xsl:text>
+            <xsl:call-template name="escape_quot">
+                <xsl:with-param name="replace" select="substring-after($replace,'"')"/>
+            </xsl:call-template>
+        </xsl:when>
+    <xsl:otherwise>
+        <xsl:value-of select="$replace"/>
+    </xsl:otherwise>
+    </xsl:choose>
+    </xsl:template>
+
 </xsl:stylesheet>
diff --git a/fence/agents/lib/fence2wiki.xsl b/fence/agents/lib/fence2wiki.xsl
new file mode 100644
index 0000000..8112169
--- /dev/null
+++ b/fence/agents/lib/fence2wiki.xsl
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xsl:stylesheet version='1.0' xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
+
+<xsl:template match="/resource-agent">
+[=#<xsl:value-of select="@name" />]
+||='''<xsl:value-of select="@shortdesc" />''' =||='''<xsl:value-of select="@name" />''' =||
+|| '''Name Of The Argument For STDIN''' || '''Name Of The Argument For Command-Line''' || '''Default Value''' ||'''Description''' ||
+<xsl:apply-templates select="parameters/parameter" />
+</xsl:template>
+
+<xsl:template match="parameters/parameter">|| <xsl:value-of select="@name" /> || <xsl:value-of select="getopt/@mixed" /> || {{{<xsl:value-of select="content/@default" disable-output-escaping="yes"/>}}} || <xsl:value-of select="shortdesc" /> ||
+</xsl:template>
+
+</xsl:stylesheet>
\ No newline at end of file
diff --git a/fence/agents/lib/fencing.py.py b/fence/agents/lib/fencing.py.py
index 798f855..ede151e 100644
--- a/fence/agents/lib/fencing.py.py
+++ b/fence/agents/lib/fencing.py.py
@@ -1,7 +1,14 @@
-#!/usr/bin/python
+#!/usr/bin/python -tt
 
 import sys, getopt, time, os, uuid, pycurl, stat
-import pexpect, re, atexit, syslog
+import pexpect, re, syslog
+import logging
+import subprocess
+import threading
+import shlex
+import exceptions
+import socket
+import textwrap
 import __main__
 
 ## do not add code here.
@@ -11,26 +18,22 @@ REDHAT_COPYRIGHT = ""
 BUILD_DATE = "March, 2008"
 #END_VERSION_GENERATION
 
-LOG_MODE_VERBOSE = 100
-LOG_MODE_QUIET = 0
+__all__ = ['atexit_handler', 'check_input', 'process_input', 'all_opt', 'show_docs',
+		'fence_login', 'fence_action', 'fence_logout']
 
-EC_GENERIC_ERROR   = 1
-EC_BAD_ARGS        = 2
-EC_LOGIN_DENIED    = 3
+EC_OK = 0
+EC_GENERIC_ERROR = 1
+EC_BAD_ARGS = 2
+EC_LOGIN_DENIED = 3
 EC_CONNECTION_LOST = 4
-EC_TIMED_OUT       = 5
-EC_WAITING_ON      = 6
-EC_WAITING_OFF     = 7
-EC_STATUS          = 8
-EC_STATUS_HMC      = 9
+EC_TIMED_OUT = 5
+EC_WAITING_ON = 6
+EC_WAITING_OFF = 7
+EC_STATUS = 8
+EC_STATUS_HMC = 9
 EC_PASSWORD_MISSING = 10
 EC_INVALID_PRIVILEGES = 11
 
-TELNET_PATH = "/usr/bin/telnet"
-SSH_PATH    = "/usr/bin/ssh"
-SSL_PATH    = "@GNUTLSCLI_PATH@"
-SUDO_PATH   = "/usr/bin/sudo"
-
 all_opt = {
 	"help"    : {
 		"getopt" : "h",
@@ -38,44 +41,44 @@ all_opt = {
 		"help" : "-h, --help                     Display this help and exit",
 		"required" : "0",
 		"shortdesc" : "Display help and exit",
-		"order" : 54 },
-	"version" : { 
+		"order" : 54},
+	"version" : {
 		"getopt" : "V",
 		"longopt" : "version",
 		"help" : "-V, --version                  Output version information and exit",
 		"required" : "0",
 		"shortdesc" : "Display version information and exit",
-		"order" : 53 },
+		"order" : 53},
 	"verbose" : {
 		"getopt" : "v",
 		"longopt" : "verbose",
 		"help" : "-v, --verbose                  Verbose mode",
 		"required" : "0",
 		"shortdesc" : "Verbose mode",
-		"order" : 51 },
+		"order" : 51},
 	"debug" : {
 		"getopt" : "D:",
-		"longopt" : "debug-file", 
+		"longopt" : "debug-file",
 		"help" : "-D, --debug-file=[debugfile]   Debugging to output file",
 		"required" : "0",
 		"shortdesc" : "Write debug information to given file",
-		"order" : 52 },
+		"order" : 52},
 	"delay" : {
-		"getopt" : "f:",
+		"getopt" : ":",
 		"longopt" : "delay",
 		"help" : "--delay=[seconds]              Wait X seconds before fencing is started",
 		"required" : "0",
 		"shortdesc" : "Wait X seconds before fencing is started",
 		"default" : "0",
-		"order" : 200 },
+		"order" : 200},
 	"agent"   : {
 		"getopt" : "",
 		"help" : "",
-		"order" : 1 },
+		"order" : 1},
 	"web"    : {
 		"getopt" : "",
 		"help" : "",
-		"order" : 1 },
+		"order" : 1},
 	"action" : {
 		"getopt" : "o:",
 		"longopt" : "action",
@@ -83,137 +86,184 @@ all_opt = {
 		"required" : "1",
 		"shortdesc" : "Fencing Action",
 		"default" : "reboot",
-		"order" : 1 },
+		"order" : 1},
 	"fabric_fencing" : {
 		"getopt" : "",
 		"help" : "",
-		"order" : 1 },
+		"order" : 1},
 	"ipaddr" : {
 		"getopt" : "a:",
 		"longopt" : "ip",
 		"help" : "-a, --ip=[ip]                  IP address or hostname of fencing device",
 		"required" : "1",
 		"shortdesc" : "IP Address or Hostname",
-		"order" : 1 },
+		"order" : 1},
 	"ipport" : {
 		"getopt" : "u:",
 		"longopt" : "ipport",
 		"help" : "-u, --ipport=[port]            TCP/UDP port to use",
 		"required" : "0",
 		"shortdesc" : "TCP/UDP port to use for connection with device",
-		"order" : 1 },		
+		"order" : 1},
 	"login" : {
 		"getopt" : "l:",
 		"longopt" : "username",
 		"help" : "-l, --username=[name]          Login name",
 		"required" : "?",
 		"shortdesc" : "Login Name",
-		"order" : 1 },
+		"order" : 1},
 	"no_login" : {
 		"getopt" : "",
 		"help" : "",
-		"order" : 1 },
+		"order" : 1},
 	"no_password" : {
 		"getopt" : "",
 		"help" : "",
-		"order" : 1 },
+		"order" : 1},
 	"no_port" : {
 		"getopt" : "",
 		"help" : "",
-		"order" : 1 },	
+		"order" : 1},
+	"no_status" : {
+		"getopt" : "",
+		"help" : "",
+		"order" : 1},
+	"telnet" : {
+		"getopt" : "",
+		"help" : "",
+		"order" : ""},
 	"passwd" : {
 		"getopt" : "p:",
 		"longopt" : "password",
 		"help" : "-p, --password=[password]      Login password or passphrase",
 		"required" : "0",
 		"shortdesc" : "Login password or passphrase",
-		"order" : 1 },
+		"order" : 1},
 	"passwd_script" : {
 		"getopt" : "S:",
 		"longopt" : "password-script",
 		"help" : "-S, --password-script=[script] Script to run to retrieve password",
 		"required" : "0",
 		"shortdesc" : "Script to retrieve password",
-		"order" : 1 },
+		"order" : 1},
 	"identity_file" : {
 		"getopt" : "k:",
 		"longopt" : "identity-file",
 		"help" : "-k, --identity-file=[filename] Identity file (private key) for ssh ",
 		"required" : "0",
 		"shortdesc" : "Identity file for ssh",
-		"order" : 1 },
+		"order" : 1},
 	"cmd_prompt" : {
 		"getopt" : "c:",
 		"longopt" : "command-prompt",
 		"help" : "-c, --command-prompt=[prompt]  Force Python regex for command prompt",
 		"shortdesc" : "Force Python regex for command prompt",
 		"required" : "0",
-		"order" : 1 },
+		"order" : 1},
 	"secure" : {
 		"getopt" : "x",
 		"longopt" : "ssh",
 		"help" : "-x, --ssh                      Use ssh connection",
 		"shortdesc" : "SSH connection",
 		"required" : "0",
-		"order" : 1 },
+		"order" : 1},
 	"ssh_options" : {
-		"getopt" : "X:",
+		"getopt" : ":",
 		"longopt" : "ssh-options",
 		"help" : "--ssh-options=[options]	  SSH options to use",
 		"shortdesc" : "SSH options to use",
 		"required" : "0",
-		"order" : 1 },
+		"order" : 1},
 	"ssl" : {
 		"getopt" : "z",
 		"longopt" : "ssl",
 		"help" : "-z, --ssl                      Use ssl connection",
 		"required" : "0",
 		"shortdesc" : "SSL connection",
-		"order" : 1 },
+		"order" : 1},
+	"ssl_insecure" : {
+		"getopt" : "",
+		"longopt" : "ssl-insecure",
+		"help" : "--ssl-insecure                 Use ssl connection without verifying certificate",
+		"required" : "0",
+		"shortdesc" : "SSL connection without verifying fence device's certificate",
+		"order" : 1},
+	"ssl_secure" : {
+		"getopt" : "",
+		"longopt" : "ssl-secure",
+		"help" : "--ssl-secure                   Use ssl connection with verifying certificate",
+		"required" : "0",
+		"shortdesc" : "SSL connection with verifying fence device's certificate",
+		"order" : 1},
+
+	"notls" : {
+		"getopt" : "t",
+		"longopt" : "notls",
+		"help" : "-t, --notls                    "
+				"Disable TLS negotiation and force SSL3.0.\n"
+				"                                        "
+				"This should only be used for devices that\n"
+				"                                        "
+				"do not support TLS1.0 and up.",
+		"required" : "0",
+		"shortdesc" : "Disable TLS negotiation, force SSL 3.0",
+		"order" : 1},
+	"tls1.0" : {
+		"getopt" : "",
+		"longopt" : "tls1.0",
+		"help" : "--tls1.0                       "
+				"Disable TLS negotiation and force TLS1.0\n"
+				"                                        "
+				"This should only be used for devices that\n"
+				"                                        "
+				"do not support TLS1.1 and up.",
+		"required" : "0",
+		"shortdesc" : "Disable TLS negotiaton, force TLS 1.0",
+		"order" : 1},
 	"port" : {
 		"getopt" : "n:",
 		"longopt" : "plug",
-		"help" : "-n, --plug=[id]                Physical plug number on device, UUID or\n" + 
+		"help" : "-n, --plug=[id]                Physical plug number on device, UUID or\n" +
         "                                        identification of machine",
 		"required" : "1",
 		"shortdesc" : "Physical plug number, name of virtual machine or UUID",
-		"order" : 1 },
+		"order" : 1},
 	"switch" : {
 		"getopt" : "s:",
 		"longopt" : "switch",
 		"help" : "-s, --switch=[id]              Physical switch number on device",
 		"required" : "0",
 		"shortdesc" : "Physical switch number on device",
-		"order" : 1 },
+		"order" : 1},
 	"exec" : {
 		"getopt" : "e:",
 		"longopt" : "exec",
 		"help" : "-e, --exec=[command]           Command to execute",
 		"required" : "0",
 		"shortdesc" : "Command to execute",
-		"order" : 1 },
+		"order" : 1},
 	"vmware_type" : {
 		"getopt" : "d:",
 		"longopt" : "vmware_type",
 		"help" : "-d, --vmware_type=[type]       Type of VMware to connect",
 		"required" : "0",
 		"shortdesc" : "Type of VMware to connect",
-		"order" : 1 },
+		"order" : 1},
 	"vmware_datacenter" : {
 		"getopt" : "s:",
 		"longopt" : "vmware-datacenter",
 		"help" : "-s, --vmware-datacenter=[dc]   VMWare datacenter filter",
 		"required" : "0",
 		"shortdesc" : "Show only machines in specified datacenter",
-		"order" : 2 },
+		"order" : 2},
 	"snmp_version" : {
 		"getopt" : "d:",
 		"longopt" : "snmp-version",
 		"help" : "-d, --snmp-version=[version]   Specifies SNMP version to use",
 		"required" : "0",
 		"shortdesc" : "Specifies SNMP version to use (1,2c,3)",
-		"choices" : [ "1", "2c", "3" ],
-		"order" : 1 },
+		"choices" : ["1", "2c", "3"],
+		"order" : 1},
 	"community" : {
 		"getopt" : "c:",
 		"longopt" : "community",
@@ -227,7 +277,7 @@ all_opt = {
 		"help" : "-b, --snmp-auth-prot=[prot]    Set authentication protocol (MD5|SHA)",
 		"required" : "0",
 		"shortdesc" : "Set authentication protocol (MD5|SHA)",
-		"choices" : [ "MD5" , "SHA" ],
+		"choices" : ["MD5", "SHA"],
 		"order" : 1},
 	"snmp_sec_level" : {
 		"getopt" : "E:",
@@ -236,7 +286,7 @@ all_opt = {
 		"                                  (noAuthNoPriv|authNoPriv|authPriv)",
 		"required" : "0",
 		"shortdesc" : "Set security level (noAuthNoPriv|authNoPriv|authPriv)",
-		"choices" : [ "noAuthNoPriv", "authNoPriv", "authPriv" ],
+		"choices" : ["noAuthNoPriv", "authNoPriv", "authPriv"],
 		"order" : 1},
 	"snmp_priv_prot" : {
 		"getopt" : "B:",
@@ -244,7 +294,7 @@ all_opt = {
 		"help" : "-B, --snmp-priv-prot=[prot]    Set privacy protocol (DES|AES)",
 		"required" : "0",
 		"shortdesc" : "Set privacy protocol (DES|AES)",
-		"choices" : [ "DES", "AES" ],
+		"choices" : ["DES", "AES"],
 		"order" : 1},
 	"snmp_priv_passwd" : {
 		"getopt" : "P:",
@@ -266,69 +316,69 @@ all_opt = {
 		"help" : "-4, --inet4-only               Forces agent to use IPv4 addresses only",
 		"required" : "0",
 		"shortdesc" : "Forces agent to use IPv4 addresses only",
-		"order" : 1 },
+		"order" : 1},
 	"inet6_only" : {
 		"getopt" : "6",
 		"longopt" : "inet6-only",
 		"help" : "-6, --inet6-only               Forces agent to use IPv6 addresses only",
 		"required" : "0",
 		"shortdesc" : "Forces agent to use IPv6 addresses only",
-		"order" : 1 },
+		"order" : 1},
 	"separator" : {
 		"getopt" : "C:",
 		"longopt" : "separator",
 		"help" : "-C, --separator=[char]         Separator for CSV created by 'list' operation",
-		"default" : ",", 
+		"default" : ",",
 		"required" : "0",
 		"shortdesc" : "Separator for CSV created by operation list",
-		"order" : 100 },
+		"order" : 100},
 	"login_timeout" : {
-		"getopt" : "y:",
+		"getopt" : ":",
 		"longopt" : "login-timeout",
 		"help" : "--login-timeout=[seconds]      Wait X seconds for cmd prompt after login",
-		"default" : "5", 
+		"default" : "5",
 		"required" : "0",
 		"shortdesc" : "Wait X seconds for cmd prompt after login",
-		"order" : 200 },
+		"order" : 200},
 	"shell_timeout" : {
-		"getopt" : "Y:",
+		"getopt" : ":",
 		"longopt" : "shell-timeout",
 		"help" : "--shell-timeout=[seconds]      Wait X seconds for cmd prompt after issuing command",
-		"default" : "3", 
+		"default" : "3",
 		"required" : "0",
 		"shortdesc" : "Wait X seconds for cmd prompt after issuing command",
-		"order" : 200 },
+		"order" : 200},
 	"power_timeout" : {
-		"getopt" : "g:",
+		"getopt" : ":",
 		"longopt" : "power-timeout",
 		"help" : "--power-timeout=[seconds]      Test X seconds for status change after ON/OFF",
-		"default" : "20", 
+		"default" : "20",
 		"required" : "0",
 		"shortdesc" : "Test X seconds for status change after ON/OFF",
-		"order" : 200 },
+		"order" : 200},
 	"power_wait" : {
-		"getopt" : "G:",
+		"getopt" : ":",
 		"longopt" : "power-wait",
 		"help" : "--power-wait=[seconds]         Wait X seconds after issuing ON/OFF",
-		"default" : "0", 
+		"default" : "0",
 		"required" : "0",
 		"shortdesc" : "Wait X seconds after issuing ON/OFF",
-		"order" : 200 },
+		"order" : 200},
 	"missing_as_off" : {
-		"getopt" : "M",
+		"getopt" : "",
 		"longopt" : "missing-as-off",
 		"help" : "--missing-as-off               Missing port returns OFF instead of failure",
 		"required" : "0",
 		"shortdesc" : "Missing port returns OFF instead of failure",
-		"order" : 200 },
+		"order" : 200},
 	"retry_on" : {
-		"getopt" : "F:",
+		"getopt" : ":",
 		"longopt" : "retry-on",
 		"help" : "--retry-on=[attempts]          Count of attempts to retry power on",
 		"default" : "1",
 		"required" : "0",
 		"shortdesc" : "Count of attempts to retry power on",
-		"order" : 201 },
+		"order" : 201},
 	"session_url" : {
 		"getopt" : "s:",
 		"longopt" : "session-url",
@@ -337,7 +387,7 @@ all_opt = {
 		"shortdesc" : "The URL of the XenServer host.",
 		"order" : 1},
 	"sudo" : {
-		"getopt" : "d",
+		"getopt" : "",
 		"longopt" : "use-sudo",
 		"help" : "--use-sudo                     Use sudo (without password) when calling 3rd party software",
 		"required" : "0",
@@ -350,65 +400,131 @@ all_opt = {
 		"required" : "0",
 		"shortdesc" : "Method to fence (onoff|cycle)",
 		"default" : "onoff",
-		"choices" : [ "onoff", "cycle" ],
+		"choices" : ["onoff", "cycle"],
+		"order" : 1},
+	"telnet_path" : {
+		"getopt" : ":",
+		"longopt" : "telnet-path",
+		"help" : "--telnet-path=[path]           Path to telnet binary",
+		"required" : "0",
+		"shortdesc" : "Path to telnet binary",
+		"default" : "@TELNET_PATH@",
+		"order": 300},
+	"ssh_path" : {
+		"getopt" : ":",
+		"longopt" : "ssh-path",
+		"help" : "--ssh-path=[path]              Path to ssh binary",
+		"required" : "0",
+		"shortdesc" : "Path to ssh binary",
+		"default" : "@SSH_PATH@",
+		"order": 300},
+	"gnutlscli_path" : {
+		"getopt" : ":",
+		"longopt" : "gnutlscli-path",
+		"help" : "--gnutlscli-path=[path]        Path to gnutls-cli binary",
+		"required" : "0",
+		"shortdesc" : "Path to gnutls-cli binary",
+		"default" : "@GNUTLSCLI_PATH@",
+		"order": 300},
+	"sudo_path" : {
+		"getopt" : ":",
+		"longopt" : "sudo-path",
+		"help" : "--sudo-path=[path]             Path to sudo binary",
+		"required" : "0",
+		"shortdesc" : "Path to sudo binary",
+		"default" : "@SUDO_PATH@",
+		"order": 300},
+	"snmpwalk_path" : {
+		"getopt" : ":",
+		"longopt" : "snmpwalk-path",
+		"help" : "--snmpwalk-path=[path]         Path to snmpwalk binary",
+		"required" : "0",
+		"shortdesc" : "Path to snmpwalk binary",
+		"default" : "@SNMPWALK_PATH@",
+		"order" : 300},
+	"snmpset_path" : {
+		"getopt" : ":",
+		"longopt" : "snmpset-path",
+		"help" : "--snmpset-path=[path]         Path to snmpset binary",
+		"required" : "0",
+		"shortdesc" : "Path to snmpset binary",
+		"default" : "@SNMPSET_PATH@",
+		"order" : 300},
+	"snmpget_path" : {
+		"getopt" : ":",
+		"longopt" : "snmpget-path",
+		"help" : "--snmpget-path=[path]         Path to snmpget binary",
+		"required" : "0",
+		"shortdesc" : "Path to snmpget binary",
+		"default" : "@SNMPGET_PATH@",
+		"order" : 300},
+	"snmp": {
+		"getopt" : "",
+		"help" : "",
+		"order" : 1},
+	"on_target": {
+		"getopt" : "",
+		"help" : "",
 		"order" : 1}
 }
 
 # options which are added automatically if 'key' is encountered ("default" is always added)
 DEPENDENCY_OPT = {
-		"default" : [ "help", "debug", "verbose", "version", "action", "agent", \
-			"power_timeout", "shell_timeout", "login_timeout", "power_wait", "retry_on", "delay" ],
-		"passwd" : [ "passwd_script" ],
-		"secure" : [ "identity_file", "ssh_options" ],
-		"ipaddr" : [ "ipport", "inet4_only", "inet6_only" ],
-		"port" : [ "separator" ],
-		"community" : [ "snmp_auth_prot", "snmp_sec_level", "snmp_priv_prot", \
-			"snmp_priv_passwd", "snmp_priv_passwd_script" ]
+		"default" : ["help", "debug", "verbose", "version", "action", "agent", \
+			"power_timeout", "shell_timeout", "login_timeout", "power_wait", "retry_on", "delay"],
+		"passwd" : ["passwd_script"],
+		"sudo" : ["sudo_path"],
+		"secure" : ["identity_file", "ssh_options", "ssh_path"],
+		"telnet" : ["telnet_path"],
+		"ipaddr" : ["ipport", "inet4_only", "inet6_only"],
+		"port" : ["separator"],
+		"ssl" : ["ssl_secure", "ssl_insecure", "gnutlscli_path"],
+		"snmp" : ["snmp_auth_prot", "snmp_sec_level", "snmp_priv_prot", \
+			"snmp_priv_passwd", "snmp_priv_passwd_script", "community", \
+			"snmpset_path", "snmpget_path", "snmpwalk_path"]
 	}
 
 class fspawn(pexpect.spawn):
 	def __init__(self, options, command):
+		logging.info("Running command: %s", command)
 		pexpect.spawn.__init__(self, command)
 		self.opt = options
-		
-	def log_expect(self, options, pattern, timeout):
+
+	def log_expect(self, pattern, timeout):
 		result = self.expect(pattern, timeout)
-		if options["log"] >= LOG_MODE_VERBOSE:
-			options["debug_fh"].write(self.before + self.after)
+		logging.debug("Received: %s", self.before + self.after)
 		return result
 
+	def send(self, message):
+		logging.debug("Sent: %s", message)
+		return pexpect.spawn.send(self, message)
+
 	# send EOL according to what was detected in login process (telnet)
 	def send_eol(self, message):
-		self.send(message + self.opt["eol"])
+		return self.send(message + self.opt["eol"])
 
 def atexit_handler():
 	try:
 		sys.stdout.close()
 		os.close(1)
 	except IOError:
-		sys.stderr.write("%s failed to close standard output\n"%(sys.argv[0]))
-		syslog.syslog(syslog.LOG_ERR, "Failed to close standard output")
+		logging.error("%s failed to close standard output\n", sys.argv[0])
 		sys.exit(EC_GENERIC_ERROR)
 
-def add_dependency_options(options):
-	## Add options which are available for every fence agent
-	added_opt = [] 
-	for x in options + ["default"]:
-		if DEPENDENCY_OPT.has_key(x):
-			added_opt.extend([y for y in DEPENDENCY_OPT[x] if options.count(y) == 0])
+def _add_dependency_options(options):
+	## Add also options which are available for every fence agent
+	added_opt = []
+	for opt in options + ["default"]:
+		if DEPENDENCY_OPT.has_key(opt):
+			added_opt.extend([y for y in DEPENDENCY_OPT[opt] if options.count(y) == 0])
 	return added_opt
 
-
-def version(command, release, build_date, copyright_notice):
-	print command, " ", release, " ", build_date
-	if len(copyright_notice) > 0:
-		print copyright_notice
-
-def fail_usage(message = ""):
+def fail_usage(message="", stop=True):
 	if len(message) > 0:
-		sys.stderr.write(message+"\n")
-	sys.stderr.write("Please use '-h' for usage\n")
-	sys.exit(EC_GENERIC_ERROR)
+		logging.error("%s\n", message)
+	if stop:
+		logging.error("Please use '-h' for usage\n")
+		sys.exit(EC_GENERIC_ERROR)
 
 def fail(error_code):
 	message = {
@@ -418,13 +534,12 @@ def fail(error_code):
 		EC_WAITING_ON : "Failed: Timed out waiting to power ON",
 		EC_WAITING_OFF : "Failed: Timed out waiting to power OFF",
 		EC_STATUS : "Failed: Unable to obtain correct plug status or plug is not available",
-		EC_STATUS_HMC :
-			"Failed: Either unable to obtain correct plug status, partition is not available or incorrect HMC version used",
+		EC_STATUS_HMC : "Failed: Either unable to obtain correct plug status, "
+				"partition is not available or incorrect HMC version used",
 		EC_PASSWORD_MISSING : "Failed: You have to set login password",
 		EC_INVALID_PRIVILEGES : "Failed: The user does not have the correct privileges to do the requested action."
 	}[error_code] + "\n"
-	sys.stderr.write(message)
-	syslog.syslog(syslog.LOG_ERR, message)
+	logging.error("%s\n", message)
 	sys.exit(EC_GENERIC_ERROR)
 
 def usage(avail_opt):
@@ -432,59 +547,41 @@ def usage(avail_opt):
 	print "\t" + os.path.basename(sys.argv[0]) + " [options]"
 	print "Options:"
 
-	sorted_list = [ (key, all_opt[key]) for key in avail_opt ]
+	sorted_list = [(key, all_opt[key]) for key in avail_opt]
 	sorted_list.sort(lambda x, y: cmp(x[1]["order"], y[1]["order"]))
 
 	for key, value in sorted_list:
 		if len(value["help"]) != 0:
 			print "   " + value["help"]
 
-def metadata(avail_opt, options, docs):
+def metadata(avail_opt, docs):
 	# avail_opt has to be unique, if there are duplicities then they should be removed
-	sorted_list = [ (key, all_opt[key]) for key in list(set(avail_opt)) ]
+	sorted_list = [(key, all_opt[key]) for key in list(set(avail_opt))]
+	sorted_list.sort(lambda x, y: cmp(x[0], y[0]))
 	sorted_list.sort(lambda x, y: cmp(x[1]["order"], y[1]["order"]))
 
 	print "<?xml version=\"1.0\" ?>"
-	print "<resource-agent name=\"" + os.path.basename(sys.argv[0]) + "\" shortdesc=\"" + docs["shortdesc"] + "\" >"
-	if "symlink" in docs:
-		for (symlink, desc) in docs["symlink"]:
-			print "<symlink name=\"" + symlink + "\" shortdesc=\"" + desc + "\"/>"
+	print "<resource-agent name=\"" + os.path.basename(sys.argv[0]) + \
+			"\" shortdesc=\"" + docs["shortdesc"] + "\" >"
+	for (symlink, desc) in docs.get("symlink", []):
+		print "<symlink name=\"" + symlink + "\" shortdesc=\"" + desc + "\"/>"
 	print "<longdesc>" + docs["longdesc"] + "</longdesc>"
-	if docs.has_key("vendorurl"):
-		print "<vendor-url>" + docs["vendorurl"] + "</vendor-url>"
+	print "<vendor-url>" + docs["vendorurl"] + "</vendor-url>"
 	print "<parameters>"
-	for option, _value in sorted_list:
+	for option, _ in sorted_list:
 		if all_opt[option].has_key("shortdesc"):
 			print "\t<parameter name=\"" + option + "\" unique=\"0\" required=\"" + all_opt[option]["required"] + "\">"
 
 			default = ""
 			if all_opt[option].has_key("default"):
-				default = str(all_opt[option]["default"])
-			elif options.has_key("--" + all_opt[option]["longopt"]) and all_opt[option]["getopt"].endswith(":"):
-				if options["--" + all_opt[option]["longopt"]]:
-					try:
-						default = options["--" + all_opt[option]["longopt"]]
-					except TypeError:
-						## @todo/@note: Currently there is no clean way how to handle lists
-						## we can create a string from it but we can't set it on command line
-						default = str(options["--" + all_opt[option]["longopt"]])
-			elif options.has_key("--" + all_opt[option]["longopt"]):
-				default = "true"
-
-			if default:
-				default = default.replace("&", "&" )
-				default = default.replace('"', """ )
-				default = default.replace('<', "<" )
-				default = default.replace('>', ">" )
-				default = default.replace("'", "'" )
-				default = "default=\"" + default + "\" "
+				default = "default=\"" + _encode_html_entities(str(all_opt[option]["default"])) + "\" "
 
 			mixed = all_opt[option]["help"]
 			## split it between option and help text
-			res = re.compile("^(.*--\S+)\s+", re.IGNORECASE | re.S).search(mixed)
-			if (None != res):
+			res = re.compile(r"^(.*?--\S+)\s+", re.IGNORECASE | re.S).search(mixed)
+			if None != res:
 				mixed = res.group(1)
-			mixed = mixed.replace("<", "<").replace(">", ">")
+			mixed = _encode_html_entities(mixed)
 			print "\t\t<getopt mixed=\"" + mixed + "\" />"
 
 			if all_opt[option].has_key("choices"):
@@ -496,323 +593,168 @@ def metadata(avail_opt, options, docs):
 				print "\t\t<content type=\"string\" "+default+" />"
 			else:
 				print "\t\t<content type=\"boolean\" "+default+" />"
-				
+
 			print "\t\t<shortdesc lang=\"en\">" + all_opt[option]["shortdesc"] + "</shortdesc>"
 			print "\t</parameter>"
 	print "</parameters>"
 	print "<actions>"
-	if avail_opt.count("fabric_fencing") == 1:
-		## do 'unfence' at the start
-		print "\t<action name=\"on\" automatic=\"1\"/>"
-	else:
-		print "\t<action name=\"on\" automatic=\"0\"/>"
-	print "\t<action name=\"off\" />"
 
-	if avail_opt.count("fabric_fencing") == 0:
-		print "\t<action name=\"reboot\" />"
+	(available_actions, _) = _get_available_actions(avail_opt)
+
+	if "on" in available_actions:
+		available_actions.remove("on")
 
-	print "\t<action name=\"status\" />"
-	print "\t<action name=\"list\" />"
-	print "\t<action name=\"monitor\" />"
-	print "\t<action name=\"metadata\" />"	
+	on_target = ' on_target="1"' if avail_opt.count("on_target") else ''
+	print "\t<action name=\"on\"%s automatic=\"%d\"/>" % (on_target, avail_opt.count("fabric_fencing"))
+
+	for action in available_actions:
+		print "\t<action name=\"%s\" />" % (action)
 	print "</actions>"
 	print "</resource-agent>"
 
 def process_input(avail_opt):
-	avail_opt.extend(add_dependency_options(avail_opt))
+	avail_opt.extend(_add_dependency_options(avail_opt))
 
-	##
-	## Set standard environment
-	#####
+	# @todo: this should be put elsewhere?
 	os.putenv("LANG", "C")
 	os.putenv("LC_ALL", "C")
 
-	##
-	## Prepare list of options for getopt
-	#####
-	getopt_string = ""
-	longopt_list = [ ]
-	for k in avail_opt:
-		if all_opt.has_key(k):
-			getopt_string += all_opt[k]["getopt"]
-		else:
-			fail_usage("Parse error: unknown option '"+k+"'")
-
-		if all_opt.has_key(k) and all_opt[k].has_key("longopt"):
-			if all_opt[k]["getopt"].endswith(":"):
-				longopt_list.append(all_opt[k]["longopt"] + "=")
-			else:
-				longopt_list.append(all_opt[k]["longopt"])
-
-	##
-	## Read options from command line or standard input
-	#####
 	if len(sys.argv) > 1:
-		try:
-			opt, _args = getopt.gnu_getopt(sys.argv[1:], getopt_string, longopt_list)
-		except getopt.GetoptError, error:
-			fail_usage("Parse error: " + error.msg)
-
-		## Transform short getopt to long one which are used in fencing agents
-		#####
-		old_opt = opt
-		opt = { }
-		for o in dict(old_opt).keys():
-			if o.startswith("--"):
-				for x in all_opt.keys():
-					if all_opt[x].has_key("longopt") and "--" + all_opt[x]["longopt"] == o:
-						opt["--" + all_opt[x]["longopt"]] = dict(old_opt)[o]
-			else:
-				for x in all_opt.keys():
-					if all_opt[x].has_key("getopt") and all_opt[x].has_key("longopt") and \
-						("-" + all_opt[x]["getopt"] == o or "-" + all_opt[x]["getopt"].rstrip(":") == o):
-						opt["--" + all_opt[x]["longopt"]] = dict(old_opt)[o]
-				opt[o] = dict(old_opt)[o]
-
-		## Compatibility Layer
-		#####
-		z = dict(opt)
-		if z.has_key("--plug") == 1:
-			z["-m"] = z["--plug"]
-
-		opt = z
-		##
-		#####
+		opt = _parse_input_cmdline(avail_opt)
 	else:
-		opt = { }
-		name = ""
-		for line in sys.stdin.readlines():
-			line = line.strip()
-			if ((line.startswith("#")) or (len(line) == 0)):
-				continue
-
-			(name, value) = (line + "=").split("=", 1)
-			value = value[:-1]
-
-			if avail_opt.count(name) == 0:
-				sys.stderr.write("Parse error: Ignoring unknown option '"+line+"'\n")
-				syslog.syslog(syslog.LOG_WARNING, "Parse error: Ignoring unknown option '"+line)
-				continue
-
-			if all_opt[name]["getopt"].endswith(":"):
-				opt["--"+all_opt[name]["longopt"].rstrip(":")] = value
-			elif value.lower() in [ "1", "yes", "on", "true" ]:
-				opt["--"+all_opt[name]["longopt"]] = "1"
+		opt = _parse_input_stdin(avail_opt)
 	return opt
 
 ##
-## This function checks input and answers if we want to have same answers 
+## This function checks input and answers if we want to have same answers
 ## in each of the fencing agents. It looks for possible errors and run
 ## password script to set a correct password
 ######
-def check_input(device_opt, opt):
+def check_input(device_opt, opt, other_conditions = False):
+	device_opt.extend(_add_dependency_options(device_opt))
 
-	device_opt.extend(add_dependency_options(device_opt))
-	
 	options = dict(opt)
 	options["device_opt"] = device_opt
 
-	## Set requirements that should be included in metadata
-	#####
-	if device_opt.count("login") and device_opt.count("no_login") == 0:
-		all_opt["login"]["required"] = "1"
-	else:
-		all_opt["login"]["required"] = "0"
-
-	if device_opt.count("fabric_fencing"):
-		all_opt["action"]["default"] = "off"
-		all_opt["action"]["help"] = "-o, --action=[action]          Action: status, off (default) or on"
-
-	## Set default values
-	#####
-	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):
-				options[getopt_long] = all_opt[opt]["default"]
-
-	if device_opt.count("ipport"):
-		if options.has_key("--ipport"):
-			all_opt["ipport"]["help"] = "-u, --ipport=[port]            TCP/UDP port to use (default "+ options["--ipport"] +")"
-		elif options.has_key("--ssh"):
-			all_opt["ipport"]["default"] = 22
-			all_opt["ipport"]["help"] = "-u, --ipport=[port]            TCP/UDP port to use (default 22)"
-		elif options.has_key("--ssl"):
-			all_opt["ipport"]["default"] = 443
-			all_opt["ipport"]["help"] = "-u, --ipport=[port]            TCP/UDP port to use (default 443)"
-		elif device_opt.count("web"):
-			all_opt["ipport"]["default"] = 80
-			if device_opt.count("ssl") == 0:
-				all_opt["ipport"]["help"] = "-u, --ipport=[port]            TCP/UDP port to use (default 80)"
-			else:
-				all_opt["ipport"]["help"] = "-u, --ipport=[port]            TCP/UDP port to use\n\
-                                        (default 80, 443 if --ssl option is used)"
-		else:
-			all_opt["ipport"]["default"] = 23
-			if device_opt.count("secure") == 0:
-				all_opt["ipport"]["help"] = "-u, --ipport=[port]            TCP/UDP port to use (default 23)"
-			else:
-				all_opt["ipport"]["help"] = "-u, --ipport=[port]            TCP/UDP port to use\n\
-                                        (default 23, 22 if --ssh option is used)"
-				
+	_update_metadata(options)
+	options = _set_default_values(options)
+	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.has_key("--action") and options["--action"].lower() == "metadata"):
-		return options
+	# OCF compatibility
+	if options["--action"] == "meta-data":
+		options["--action"] = "metadata"
 
-	options["--action"] = options["--action"].lower()
+	if options["--action"] == "metadata" or any(options.has_key(k) for k in ("--help", "--version")):
+		return options
 
 	if options.has_key("--verbose"):
-		options["log"] = LOG_MODE_VERBOSE
-	else:
-		options["log"] = LOG_MODE_QUIET
+		logging.getLogger().setLevel(logging.DEBUG)
+
+	## add logging to syslog
+	logging.getLogger().addHandler(SyslogLibHandler())
+	## add logging to stderr
+	logging.getLogger().addHandler(logging.StreamHandler(stream=sys.stderr))
+
+	(acceptable_actions, _) = _get_available_actions(device_opt)
 
-	acceptable_actions = [ "on", "off", "status", "list", "monitor" ]
 	if 1 == device_opt.count("fabric_fencing"):
-		## Compatibility layer
-		#####
 		acceptable_actions.extend(["enable", "disable"])
-	else:
-		acceptable_actions.extend(["reboot"])
 
 	if 0 == acceptable_actions.count(options["--action"]):
 		fail_usage("Failed: Unrecognised action '" + options["--action"] + "'")
 
-	## Compatibility layer 
+	## Compatibility layer
 	#####
 	if options["--action"] == "enable":
 		options["--action"] = "on"
 	if options["--action"] == "disable":
 		options["--action"] = "off"
 
-	## automatic detection and set of valid UUID from --plug
-	if (0 == 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"):
-		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")):
-				fail_usage("Failed: You have to enter password or password script")
-		else: 
-			if 0 == (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"):
-		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"]):
-			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:
-		fail_usage("Failed: You have to enter plug number or machine identification")
-
-	if options.has_key("--password-script"):
-		options["--password"] = os.popen(options["--password-script"]).read().rstrip()
+	if options["--action"] == "validate-all" and not other_conditions:
+		_validate_input(options, False)
+		sys.exit(EC_OK)
+	else:
+		_validate_input(options, True)
 
 	if options.has_key("--debug-file"):
 		try:
-			options["debug_fh"] = file (options["--debug-file"], "w")
+			debug_file = logging.FileHandler(options["--debug-file"])
+			debug_file.setLevel(logging.DEBUG)
+			logging.getLogger().addHandler(debug_file)
 		except IOError:
+			logging.error("Unable to create file %s", options["--debug-file"])
 			fail_usage("Failed: Unable to create file " + options["--debug-file"])
 
-	if options.has_key("debug_fh") == 0:
-		options["debug_fh"] = sys.stderr
-
 	if options.has_key("--snmp-priv-passwd-script"):
 		options["--snmp-priv-passwd"] = os.popen(options["--snmp-priv-passwd-script"]).read().rstrip()
 
-	if options.has_key("--ipport") == False:
-		if options.has_key("--ssh"):
-			options["--ipport"] = 22
-		elif options.has_key("--ssl"):
-			options["--ipport"] = 443
-		elif device_opt.count("web"):
-			options["--ipport"] = 80
-		else:
-			options["--ipport"] = 23
-
-	if options.has_key("--plug") and len(options["--plug"].split(",")) > 1 and options.has_key("--method") and options["--method"] == "cycle":
-		fail_usage("Failed: Cannot use --method cycle for more than 1 plug")
-
-	for opt in device_opt:
-		if all_opt[opt].has_key("choices"):
-			long = "--" + all_opt[opt]["longopt"]
-			possible_values_upper = map (lambda y : y.upper(), all_opt[opt]["choices"])
-			if options.has_key(long):
-				options[long] = options[long].upper()
-				if not options["--" + all_opt[opt]["longopt"]] in possible_values_upper:
-					fail_usage("Failed: You have to enter a valid choice for %s from the valid values: %s" % ("--" + all_opt[opt]["longopt"] , str(all_opt[opt]["choices"])))
+	if options.has_key("--password-script"):
+		options["--password"] = os.popen(options["--password-script"]).read().rstrip()
 
 	return options
-	
-def wait_power_status(tn, options, get_power_fn):
-	for dummy in xrange(int(options["--power-timeout"])):
-		if get_multi_power_fn(tn, options, get_power_fn) != options["--action"]:
-			time.sleep(1)
-		else:
-			return 1
-	return 0
 
 ## Obtain a power status from possibly more than one plug
 ##	"on" is returned if at least one plug is ON
 ######
-def get_multi_power_fn(tn, options, get_power_fn):
+def get_multi_power_fn(connection, options, get_power_fn):
 	status = "off"
+	plugs = options["--plugs"] if options.has_key("--plugs") else [""]
 
-	if options.has_key("--plugs"):
-		for plug in options["--plugs"]:
-			try:
-				options["--uuid"] = str(uuid.UUID(plug))
-			except ValueError:
-				pass
-			except KeyError:
-				pass
+	for plug in plugs:
+		try:
+			options["--uuid"] = str(uuid.UUID(plug))
+		except ValueError:
+			pass
+		except KeyError:
+			pass
+
+		options["--plug"] = plug
+		plug_status = get_power_fn(connection, options)
+		if plug_status != "off":
+			status = plug_status
 
-			options["--plug"] = plug
-			plug_status = get_power_fn(tn, options)
-			if plug_status != "off":
-				status = plug_status
-	else:
-		status = get_power_fn(tn, options)
-	
 	return status
 
-def set_multi_power_fn(tn, options, set_power_fn):
-	if options.has_key("--plugs"):
-		for plug in options["--plugs"]:
+def set_multi_power_fn(connection, options, set_power_fn, get_power_fn, retry_attempts=1):
+	plugs = options["--plugs"] if options.has_key("--plugs") else [""]
+
+	for _ in range(retry_attempts):
+		for plug in plugs:
 			try:
 				options["--uuid"] = str(uuid.UUID(plug))
 			except ValueError:
 				pass
 			except KeyError:
 				pass
+
 			options["--plug"] = plug
-			set_power_fn(tn, options)
-	else:
-		set_power_fn(tn, options)
+			set_power_fn(connection, options)
+			time.sleep(int(options["--power-wait"]))
+
+		for _ in xrange(int(options["--power-timeout"])):
+			if get_multi_power_fn(connection, options, get_power_fn) != options["--action"]:
+				time.sleep(1)
+			else:
+				return True
+	return False
 
-def show_docs(options, docs = None):
+def show_docs(options, docs=None):
 	device_opt = options["device_opt"]
 
 	if docs == None:
-		docs = { }
+		docs = {}
 		docs["shortdesc"] = "Fence agent"
 		docs["longdesc"] = ""
-	
-	## Process special options (and exit)
-	#####
-	if options.has_key("--help"): 
+
+	if options.has_key("--help"):
 		usage(device_opt)
 		sys.exit(0)
 
-	if options.has_key("--action") and options["--action"].lower() == "metadata":
-		metadata(device_opt, options, docs)
+	if options.get("--action", "") == "metadata":
+		metadata(device_opt, docs)
 		sys.exit(0)
 
 	if options.has_key("--version"):
@@ -820,7 +762,7 @@ def show_docs(options, docs = None):
 		print __main__.REDHAT_COPYRIGHT
 		sys.exit(0)
 
-def fence_action(tn, options, set_power_fn, get_power_fn, get_outlet_list = None, reboot_cycle_fn = None):
+def fence_action(connection, options, set_power_fn, get_power_fn, get_outlet_list=None, reboot_cycle_fn=None):
 	result = 0
 
 	try:
@@ -829,60 +771,60 @@ def fence_action(tn, options, set_power_fn, get_power_fn, get_outlet_list = None
 
 		## Process options that manipulate fencing device
 		#####
-		if (options["--action"] == "list") and 0 == options["device_opt"].count("port"):
-			print "N/A"
-			return
-		elif (options["--action"] == "list" and get_outlet_list == None):
-			## @todo: exception?
-			## This is just temporal solution, we will remove default value
-			## None as soon as all existing agent will support this operation 
-			print "NOTICE: List option is not working on this device yet"
-			return
-		elif (options["--action"] == "list") or ((options["--action"] == "monitor") and 1 == options["device_opt"].count("port")):
-			outlets = get_outlet_list(tn, options)
-			## keys can be numbers (port numbers) or strings (names of VM)
-			for o in outlets.keys():
-				(alias, status) = outlets[o]
-				if options["--action"] != "monitor":
-					print o + options["--separator"] + alias	
+		if (options["--action"] in ["list", "list-status"]) or \
+			((options["--action"] == "monitor") and 1 == options["device_opt"].count("port")):
+
+			if 0 == options["device_opt"].count("port"):
+				print "N/A"
+			elif get_outlet_list == None:
+				## @todo: exception?
+				## This is just temporal solution, we will remove default value
+				## None as soon as all existing agent will support this operation
+				print "NOTICE: List option is not working on this device yet"
+			else:
+				original_action = options["--action"]
+				options["--action"] = "list"
+				outlets = get_outlet_list(connection, options)
+				options["--action"] = original_action
+
+				## keys can be numbers (port numbers) or strings (names of VM, UUID)
+				for outlet_id in outlets.keys():
+					(alias, status) = outlets[outlet_id]
+					status = status.upper()
+					if not status in ["ON", "OFF"]:
+						status = "UNKNOWN"
+
+					if options["--action"] == "list":
+						print outlet_id + options["--separator"] + alias
+					elif options["--action"] == "list-status":
+						print outlet_id + options["--separator"] + alias + options["--separator"] + status
+
 			return
 
-		status = get_multi_power_fn(tn, options, get_power_fn)
+		status = get_multi_power_fn(connection, options, get_power_fn)
 
-		if status != "on" and status != "off":  
+		if status != "on" and status != "off":
 			fail(EC_STATUS)
 
+		if options["--action"] == status:
+			print "Success: Already %s" % (status.upper())
+			return 0
+
 		if options["--action"] == "on":
-			if status == "on":
-				print "Success: Already ON"
+			if set_multi_power_fn(connection, options, set_power_fn, get_power_fn, 1 + int(options["--retry-on"])):
+				print "Success: Powered ON"
 			else:
-				power_on = False
-				for _ in range(1, 1 + int(options["--retry-on"])):
-					set_multi_power_fn(tn, options, set_power_fn)
-					time.sleep(int(options["--power-wait"]))
-					if wait_power_status(tn, options, get_power_fn):
-						power_on = True
-						break
-
-				if power_on:
-					print "Success: Powered ON"
-				else:
-					fail(EC_WAITING_ON)
+				fail(EC_WAITING_ON)
 		elif options["--action"] == "off":
-			if status == "off":
-				print "Success: Already OFF"
+			if set_multi_power_fn(connection, options, set_power_fn, get_power_fn):
+				print "Success: Powered OFF"
 			else:
-				set_multi_power_fn(tn, options, set_power_fn)
-				time.sleep(int(options["--power-wait"]))
-				if wait_power_status(tn, options, get_power_fn):
-					print "Success: Powered OFF"
-				else:
-					fail(EC_WAITING_OFF)
+				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):
+					if reboot_cycle_fn(connection, options):
 						power_on = True
 						break
 
@@ -892,30 +834,21 @@ def fence_action(tn, options, set_power_fn, get_power_fn, get_outlet_list = None
 			else:
 				if status != "off":
 					options["--action"] = "off"
-					set_multi_power_fn(tn, options, set_power_fn)
-					time.sleep(int(options["--power-wait"]))
-					if wait_power_status(tn, options, get_power_fn) == 0:
+					if not set_multi_power_fn(connection, options, set_power_fn, get_power_fn):
 						fail(EC_WAITING_OFF)
+
 				options["--action"] = "on"
 
 				try:
-					for _ in range(1, 1 + int(options["--retry-on"])):
-						set_multi_power_fn(tn, options, set_power_fn)
-						time.sleep(int(options["--power-wait"]))
-						if wait_power_status(tn, options, get_power_fn) == 1:
-							power_on = True
-							break
+					power_on = set_multi_power_fn(connection, options, set_power_fn, get_power_fn, int(options["--retry-on"]))
 				except Exception, ex:
 					# an error occured during power ON phase in reboot
 					# fence action was completed succesfully even in that case
-					sys.stderr.write(str(ex))
-					syslog.syslog(syslog.LOG_NOTICE, str(ex))
-					pass
+					logging.warning("%s", str(ex))
 
 			if power_on == False:
 				# this should not fail as node was fenced succesfully
-				sys.stderr.write('Timed out waiting to power ON\n')
-				syslog.syslog(syslog.LOG_NOTICE, "Timed out waiting to power ON")
+				logging.error('Timed out waiting to power ON\n')
 
 			print "Success: Rebooted"
 		elif options["--action"] == "status":
@@ -929,142 +862,34 @@ def fence_action(tn, options, set_power_fn, get_power_fn, get_outlet_list = None
 	except pexpect.TIMEOUT:
 		fail(EC_TIMED_OUT)
 	except pycurl.error, ex:
-		sys.stderr.write(ex[1] + "\n")
-		syslog.syslog(syslog.LOG_ERR, ex[1])
+		logging.error("%s\n", str(ex))
+		fail(EC_TIMED_OUT)
+	except socket.timeout, ex:
+		logging.error("%s\n", str(ex))
 		fail(EC_TIMED_OUT)
-	
-	return result
-
-def fence_login(options, re_login_string = "(login\s*: )|(Login Name:  )|(username: )|(User Name :)"):
-	force_ipvx=""
 
-	if (options.has_key("--inet6-only")):
-		force_ipvx = "-6 "
+	return result
 
-	if (options.has_key("--inet4-only")):
-		force_ipvx = "-4 "
+def fence_login(options, re_login_string=r"(login\s*: )|((?!Last )Login Name:  )|(username: )|(User Name :)"):
+	run_delay(options)
 
-	if (options.has_key("eol") == False):
+	if not options.has_key("eol"):
 		options["eol"] = "\r\n"
 
 	if options.has_key("--command-prompt") and type(options["--command-prompt"]) is not list:
-		options["--command-prompt"] = [ options["--command-prompt"] ]
-
-	## Do the delay of the fence device before logging in
-	## Delay is important for two-node clusters fencing but we do not need to delay 'status' operations
-	if options["--action"] in ["off", "reboot"]:
-		time.sleep(int(options["--delay"]))
+		options["--command-prompt"] = [options["--command-prompt"]]
 
 	try:
-		re_login = re.compile(re_login_string, re.IGNORECASE)
-		re_pass  = re.compile("(password)|(pass phrase)", re.IGNORECASE)
-
 		if options.has_key("--ssl"):
-			command = '%s --insecure --crlf -p %s %s' % (SSL_PATH, options["--ipport"], options["--ip"])
-			try:
-				conn = fspawn(options, command)
-			except pexpect.ExceptionPexpect, ex:
-				sys.stderr.write(str(ex) + "\n")
-				syslog.syslog(syslog.LOG_ERR, str(ex))
-				sys.exit(EC_GENERIC_ERROR)
-		elif options.has_key("--ssh") and 0 == 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"):
-				command += ' ' + options["--ssh-options"]
-			try:
-				conn = fspawn(options, command)
-			except pexpect.ExceptionPexpect, ex:
-				sys.stderr.write(str(ex) + "\n")
-				syslog.syslog(syslog.LOG_ERR, str(ex))
-				sys.stderr.write("Due to limitations, binary dependencies on fence agents "
-				"are not in the spec file and must be installed separately." + "\n")
-				sys.exit(EC_GENERIC_ERROR)
-				
-			if options.has_key("telnet_over_ssh"):
-				#This is for stupid ssh servers (like ALOM) which behave more like telnet (ignore name and display login prompt)
-				result = conn.log_expect(options, [ re_login, "Are you sure you want to continue connecting (yes/no)?" ], int(options["--login-timeout"]))
-				if result == 1:
-					conn.sendline("yes") # Host identity confirm
-					conn.log_expect(options, re_login, int(options["--login-timeout"]))
-
-				conn.sendline(options["--username"])
-				conn.log_expect(options, re_pass, int(options["--login-timeout"]))
-			else:
-				result = conn.log_expect(options, [ "ssword:", "Are you sure you want to continue connecting (yes/no)?" ], int(options["--login-timeout"]))
-				if result == 1:
-					conn.sendline("yes")
-					conn.log_expect(options, "ssword:", int(options["--login-timeout"]))
-
-			conn.sendline(options["--password"])
-			conn.log_expect(options, options["--command-prompt"], int(options["--login-timeout"]))
+			conn = _open_ssl_connection(options)
+		elif options.has_key("--ssh") and not options.has_key("--identity-file"):
+			conn = _login_ssh_with_password(options, re_login_string)
 		elif options.has_key("--ssh") and options.has_key("--identity-file"):
-			command = '%s %s %s@%s -i %s -p %s' % (SSH_PATH, force_ipvx, options["--username"], options["--ip"], options["--identity-file"], options["--ipport"])
-			if options.has_key("--ssh-options"):
-				command += ' ' + options["--ssh-options"]
-			try:
-				conn = fspawn(options, command)
-			except pexpect.ExceptionPexpect, ex:
-				sys.stderr.write(str(ex) + "\n")
-				syslog.syslog(syslog.LOG_ERR, str(ex))
-				sys.stderr.write("Due to limitations, binary dependencies on fence agents "
-				"are not in the spec file and must be installed separately." + "\n")
-				sys.exit(EC_GENERIC_ERROR)
-
-			result = conn.log_expect(options, [ options["--command-prompt"], \
-				"Are you sure you want to continue connecting (yes/no)?", \
-				"Enter passphrase for key '" + options["--identity-file"] + "':" ], int(options["--login-timeout"]))
-			if result == 1:
-				conn.sendline("yes")
-				conn.log_expect(options, [ options["--command-prompt"], "Enter passphrase for key '"+options["--identity-file"]+"':"] , int(options["--login-timeout"]))
-			if result != 0:
-				if options.has_key("--password"):
-					conn.sendline(options["--password"])
-					conn.log_expect(options, options["--command-prompt"], int(options["--login-timeout"]))
-				else:
-					fail_usage("Failed: You have to enter passphrase (-p) for identity file")
+			conn = _login_ssh_with_identity_file(options)
 		else:
-			try:
-				conn = fspawn(options, TELNET_PATH)
-				conn.send("set binary\n")
-				conn.send("open %s -%s\n"%(options["--ip"], options["--ipport"]))
-			except pexpect.ExceptionPexpect, ex:
-				sys.stderr.write(str(ex) + "\n")
-				syslog.syslog(syslog.LOG_ERR, str(ex))
-				sys.stderr.write("Due to limitations, binary dependencies on fence agents "
-				"are not in the spec file and must be installed separately." + "\n")
-				sys.exit(EC_GENERIC_ERROR)
-
-			result = conn.log_expect(options, re_login, int(options["--login-timeout"]))
-			conn.send_eol(options["--username"])
-
-			## automatically change end of line separator
-			screen = conn.read_nonblocking(size=100, timeout=int(options["--shell-timeout"]))
-			if (re_login.search(screen) != None):
-				options["eol"] = "\n"
-				conn.send_eol(options["--username"])
-				result = conn.log_expect(options, re_pass, int(options["--login-timeout"]))
-			elif (re_pass.search(screen) == None):
-				conn.log_expect(options, re_pass, int(options["--shell-timeout"]))
-
-			try:
-				conn.send_eol(options["--password"])
-				valid_password = conn.log_expect(options, [ re_login ] + options["--command-prompt"], int(options["--shell-timeout"]))
-				if valid_password == 0:
-					## password is invalid or we have to change EOL separator
-					options["eol"] = "\r"
-					conn.send_eol("")
-					screen = conn.read_nonblocking(size=100, timeout=int(options["--shell-timeout"]))
-					## after sending EOL the fence device can either show 'Login' or 'Password'
-					if (re_login.search(screen) != None):
-						conn.send_eol("")
-					conn.send_eol(options["--username"])
-					conn.log_expect(options, re_pass, int(options["--login-timeout"]))
-					conn.send_eol(options["--password"])
-					conn.log_expect(options, options["--command-prompt"], int(options["--login-timeout"]))
-			except KeyError:
-				fail(EC_PASSWORD_MISSING)
+			conn = _login_telnet(options, re_login_string)
 	except pexpect.EOF:
-		fail(EC_LOGIN_DENIED) 
+		fail(EC_LOGIN_DENIED)
 	except pexpect.TIMEOUT:
 		fail(EC_LOGIN_DENIED)
 	return conn
@@ -1075,3 +900,469 @@ def is_executable(path):
 		if stat.S_ISREG(stats.st_mode) and os.access(path, os.X_OK):
 			return True
 	return False
+
+def run_command(options, command, timeout=None, env=None):
+	if timeout is None and "--power-timeout" in options:
+		timeout = options["--power-timeout"]
+	if timeout is not None:
+		timeout = float(timeout)
+
+	logging.info("Executing: %s\n", command)
+
+	try:
+		process = subprocess.Popen(shlex.split(command), stdout=subprocess.PIPE, stderr=subprocess.PIPE, env=env)
+	except OSError:
+		fail_usage("Unable to run %s\n" % command)
+
+	thread = threading.Thread(target=process.wait)
+	thread.start()
+	thread.join(timeout)
+	if thread.is_alive():
+		process.kill()
+		fail(EC_TIMED_OUT)
+
+	status = process.wait()
+
+	(pipe_stdout, pipe_stderr) = process.communicate()
+	process.stdout.close()
+	process.stderr.close()
+
+	logging.debug("%s %s %s\n", str(status), str(pipe_stdout), str(pipe_stderr))
+
+	return (status, pipe_stdout, pipe_stderr)
+
+def run_delay(options):
+	## Delay is important for two-node clusters fencing but we do not need to delay 'status' operations
+	if options["--action"] in ["off", "reboot"]:
+		logging.info("Delay %s second(s) before logging in to the fence device", options["--delay"])
+		time.sleep(int(options["--delay"]))
+
+def fence_logout(conn, logout_string, sleep=0):
+	# Logout is not required part of fencing but we should attempt to do it properly
+	# In some cases our 'exit' command is faster and we can not close connection as it
+	# was already closed by fencing device
+	try:
+		conn.send_eol(logout_string)
+		time.sleep(sleep)
+		conn.close()
+	except exceptions.OSError:
+		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(array):
+	return dict([[x[0].split(".")[-1], x[1]] for x in array])
+
+## Own logger handler that uses old-style syslog handler as otherwise everything is sourced
+## from /dev/syslog
+class SyslogLibHandler(logging.StreamHandler):
+	"""
+	A handler class that correctly push messages into syslog
+	"""
+	def emit(self, record):
+		syslog_level = {
+			logging.CRITICAL:syslog.LOG_CRIT,
+			logging.ERROR:syslog.LOG_ERR,
+			logging.WARNING:syslog.LOG_WARNING,
+			logging.INFO:syslog.LOG_INFO,
+			logging.DEBUG:syslog.LOG_DEBUG,
+			logging.NOTSET:syslog.LOG_DEBUG,
+		}[record.levelno]
+
+		msg = self.format(record)
+
+		# syslos.syslog can not have 0x00 character inside or exception is thrown
+		syslog.syslog(syslog_level, msg.replace("\x00", "\n"))
+		return
+
+def _open_ssl_connection(options):
+	gnutls_opts = ""
+	ssl_opts = ""
+
+	if options.has_key("--notls"):
+		gnutls_opts = "--priority \"NORMAL:-VERS-TLS1.2:-VERS-TLS1.1:-VERS-TLS1.0:+VERS-SSL3.0\""
+	elif options.has_key("--tls1.0"):
+		gnutls_opts = "--priority \"NORMAL:-VERS-TLS1.2:-VERS-TLS1.1:+VERS-TLS1.0:%LATEST_RECORD_VERSION\""
+
+	# --ssl is same as the --ssl-secure; it means we want to verify certificate in these cases
+	if options.has_key("--ssl-insecure"):
+		ssl_opts = "--insecure"
+
+	command = '%s %s %s --crlf -p %s %s' % \
+		(options["--gnutlscli-path"], gnutls_opts, ssl_opts, options["--ipport"], options["--ip"])
+	try:
+		conn = fspawn(options, command)
+	except pexpect.ExceptionPexpect, ex:
+		logging.error("%s\n", str(ex))
+		sys.exit(EC_GENERIC_ERROR)
+
+	return conn
+
+def _login_ssh_with_identity_file(options):
+	if options.has_key("--inet6-only"):
+		force_ipvx = "-6 "
+	elif options.has_key("--inet4-only"):
+		force_ipvx = "-4 "
+	else:
+		force_ipvx = ""
+
+	command = '%s %s %s@%s -i %s -p %s' % \
+		(options["--ssh-path"], force_ipvx, options["--username"], options["--ip"], \
+		options["--identity-file"], options["--ipport"])
+	if options.has_key("--ssh-options"):
+		command += ' ' + options["--ssh-options"]
+
+	conn = fspawn(options, command)
+
+	result = conn.log_expect(["Enter passphrase for key '" + options["--identity-file"] + "':", \
+		"Are you sure you want to continue connecting (yes/no)?"] + \
+		options["--command-prompt"], int(options["--login-timeout"]))
+	if result == 1:
+		conn.sendline("yes")
+		result = conn.log_expect(
+			["Enter passphrase for key '" + options["--identity-file"]+"':"] + \
+			options["--command-prompt"], int(options["--login-timeout"]))
+	if result == 0:
+		if options.has_key("--password"):
+			conn.sendline(options["--password"])
+			conn.log_expect(options["--command-prompt"], int(options["--login-timeout"]))
+		else:
+			fail_usage("Failed: You have to enter passphrase (-p) for identity file")
+
+	return conn
+
+def _login_telnet(options, re_login_string):
+	re_login = re.compile(re_login_string, re.IGNORECASE)
+	re_pass = re.compile("(password)|(pass phrase)", re.IGNORECASE)
+
+	conn = fspawn(options, options["--telnet-path"])
+	conn.send("set binary\n")
+	conn.send("open %s -%s\n"%(options["--ip"], options["--ipport"]))
+
+	conn.log_expect(re_login, int(options["--login-timeout"]))
+	conn.send_eol(options["--username"])
+
+	## automatically change end of line separator
+	screen = conn.read_nonblocking(size=100, timeout=int(options["--shell-timeout"]))
+	if re_login.search(screen) != None:
+		options["eol"] = "\n"
+		conn.send_eol(options["--username"])
+		conn.log_expect(re_pass, int(options["--login-timeout"]))
+	elif re_pass.search(screen) != None:
+		conn.log_expect(re_pass, int(options["--shell-timeout"]))
+
+	try:
+		conn.send_eol(options["--password"])
+		valid_password = conn.log_expect([re_login] + \
+				options["--command-prompt"], int(options["--shell-timeout"]))
+		if valid_password == 0:
+			## password is invalid or we have to change EOL separator
+			options["eol"] = "\r"
+			conn.send_eol("")
+			screen = conn.read_nonblocking(size=100, timeout=int(options["--shell-timeout"]))
+			## after sending EOL the fence device can either show 'Login' or 'Password'
+			if re_login.search(screen) != None:
+				conn.send_eol("")
+			conn.send_eol(options["--username"])
+			conn.log_expect(re_pass, int(options["--login-timeout"]))
+			conn.send_eol(options["--password"])
+			conn.log_expect(options["--command-prompt"], int(options["--login-timeout"]))
+	except KeyError:
+		fail(EC_PASSWORD_MISSING)
+
+	return conn
+
+def _login_ssh_with_password(options, re_login_string):
+	re_login = re.compile(re_login_string, re.IGNORECASE)
+	re_pass = re.compile("(password)|(pass phrase)", re.IGNORECASE)
+
+	if options.has_key("--inet6-only"):
+		force_ipvx = "-6 "
+	elif options.has_key("--inet4-only"):
+		force_ipvx = "-4 "
+	else:
+		force_ipvx = ""
+
+	command = '%s %s %s@%s -p %s -o PubkeyAuthentication=no' % \
+			(options["--ssh-path"], force_ipvx, options["--username"], options["--ip"], options["--ipport"])
+	if options.has_key("--ssh-options"):
+		command += ' ' + options["--ssh-options"]
+
+	conn = fspawn(options, command)
+
+	if options.has_key("telnet_over_ssh"):
+		# This is for stupid ssh servers (like ALOM) which behave more like telnet
+		# (ignore name and display login prompt)
+		result = conn.log_expect( \
+				[re_login, "Are you sure you want to continue connecting (yes/no)?"],
+				int(options["--login-timeout"]))
+		if result == 1:
+			conn.sendline("yes") # Host identity confirm
+			conn.log_expect(re_login, int(options["--login-timeout"]))
+
+		conn.sendline(options["--username"])
+		conn.log_expect(re_pass, int(options["--login-timeout"]))
+	else:
+		result = conn.log_expect( \
+				["ssword:", "Are you sure you want to continue connecting (yes/no)?"],
+				int(options["--login-timeout"]))
+		if result == 1:
+			conn.sendline("yes")
+			conn.log_expect("ssword:", int(options["--login-timeout"]))
+
+	conn.sendline(options["--password"])
+	conn.log_expect(options["--command-prompt"], int(options["--login-timeout"]))
+
+	return conn
+
+#
+# To update metadata, we change values in all_opt
+def _update_metadata(options):
+	device_opt = options["device_opt"]
+
+	if device_opt.count("login") and device_opt.count("no_login") == 0:
+		all_opt["login"]["required"] = "1"
+	else:
+		all_opt["login"]["required"] = "0"
+
+	(available_actions, default_value) = _get_available_actions(device_opt)
+	all_opt["action"]["default"] = default_value
+
+	actions_with_default = \
+			[x if not x == all_opt["action"]["default"] else x + " (default)" for x in available_actions]
+	all_opt["action"]["help"] = \
+			"-o, --action=[action]          Action: %s" % (_join_wrap(actions_with_default, last_separator=" or "))
+
+	if device_opt.count("ipport"):
+		default_value = None
+		default_string = None
+
+		if all_opt["ipport"].has_key("default"):
+			default_value = all_opt["ipport"]["default"]
+		elif device_opt.count("web") and device_opt.count("ssl"):
+			default_value = "80"
+			default_string = "(default 80, 443 if --ssl option is used)"
+		elif device_opt.count("telnet") and device_opt.count("secure"):
+			default_value = "23"
+			default_string = "(default 23, 22 if --ssh option is used)"
+		else:
+			tcp_ports = {"community" : "161", "secure" : "22", "telnet" : "23", "web" : "80", "ssl" : "443"}
+			# all cases where next command returns multiple results are covered by previous blocks
+			protocol = [x for x in ["community", "secure", "ssl", "web", "telnet"] if device_opt.count(x)][0]
+			default_value = tcp_ports[protocol]
+
+		if default_string is None:
+			all_opt["ipport"]["help"] = "-u, --ipport=[port]            TCP/UDP port to use (default %s)" % \
+					(default_value)
+		else:
+			all_opt["ipport"]["help"] = "-u, --ipport=[port]            TCP/UDP port to use\n" + " "*40 + default_string
+
+def _set_default_values(options):
+	if "ipport" in options["device_opt"]:
+		if not "--ipport" in options:
+			if "default" in all_opt["ipport"]:
+				options["--ipport"] = all_opt["ipport"]["default"]
+			elif "community" in options["device_opt"]:
+				options["--ipport"] = "161"
+			elif "--ssh" in options or all_opt["secure"].get("default", "0") == "1":
+				options["--ipport"] = "22"
+			elif "--ssl" in options or all_opt["ssl"].get("default", "0") == "1":
+				options["--ipport"] = "443"
+			elif "--ssl-secure" in options or all_opt["ssl_secure"].get("default", "0") == "1":
+				options["--ipport"] = "443"
+			elif "--ssl-insecure" in options or all_opt["ssl_insecure"].get("default", "0") == "1":
+				options["--ipport"] = "443"
+			elif "web" in options["device_opt"]:
+				options["--ipport"] = "80"
+			elif "telnet" in options["device_opt"]:
+				options["--ipport"] = "23"
+
+			if "--ipport" in options:
+				all_opt["ipport"]["default"] = options["--ipport"]
+
+	for opt in options["device_opt"]:
+		if all_opt[opt].has_key("default") and not opt == "ipport":
+			getopt_long = "--" + all_opt[opt]["longopt"]
+			if not options.has_key(getopt_long):
+				options[getopt_long] = all_opt[opt]["default"]
+
+	return options
+
+# stop = True/False : exit fence agent when problem is encountered
+def _validate_input(options, stop = True):
+	device_opt = options["device_opt"]
+	valid_input = True
+
+	if not options.has_key("--username") and \
+			device_opt.count("login") and (device_opt.count("no_login") == 0):
+		valid_input = False
+		fail_usage("Failed: You have to set login name", stop)
+
+	if device_opt.count("ipaddr") and not options.has_key("--ip") and not options.has_key("--managed"):
+		valid_input = False
+		fail_usage("Failed: You have to enter fence address", stop)
+
+	if device_opt.count("no_password") == 0:
+		if 0 == device_opt.count("identity_file"):
+			if not (options.has_key("--password") or options.has_key("--password-script")):
+				valid_input = False
+				fail_usage("Failed: You have to enter password or password script", stop)
+		else:
+			if not (options.has_key("--password") or \
+					options.has_key("--password-script") or options.has_key("--identity-file")):
+				valid_input = False
+				fail_usage("Failed: You have to enter password, password script or identity file", stop)
+
+	if not options.has_key("--ssh") and options.has_key("--identity-file"):
+		valid_input = False
+		fail_usage("Failed: You have to use identity file together with ssh connection (-x)", stop)
+
+	if options.has_key("--identity-file") and not os.path.isfile(options["--identity-file"]):
+		valid_input = False
+		fail_usage("Failed: Identity file " + options["--identity-file"] + " does not exist", stop)
+
+	if (0 == ["list", "list-status", "monitor"].count(options["--action"])) and \
+		not options.has_key("--plug") and device_opt.count("port") and device_opt.count("no_port") == 0:
+		valid_input = False
+		fail_usage("Failed: You have to enter plug number or machine identification", stop)
+
+	if options.has_key("--plug") and len(options["--plug"].split(",")) > 1 and \
+			options.has_key("--method") and options["--method"] == "cycle":
+		valid_input = False
+		fail_usage("Failed: Cannot use --method cycle for more than 1 plug", stop)
+
+	for failed_opt in _get_opts_with_invalid_choices(options):
+		valid_input = False
+		fail_usage("Failed: You have to enter a valid choice for %s from the valid values: %s" % \
+			("--" + all_opt[failed_opt]["longopt"], str(all_opt[failed_opt]["choices"])), stop)
+
+	return valid_input
+
+def _encode_html_entities(text):
+	return text.replace("&", "&").replace('"', """).replace('<', "<"). \
+		replace('>', ">").replace("'", "'")
+
+def _prepare_getopt_args(options):
+	getopt_string = ""
+	longopt_list = []
+	for k in options:
+		if all_opt.has_key(k) and all_opt[k]["getopt"] != ":":
+			# getopt == ":" means that opt is without short getopt, but has value
+			getopt_string += all_opt[k]["getopt"]
+		elif not all_opt.has_key(k):
+			fail_usage("Parse error: unknown option '"+k+"'")
+
+		if all_opt.has_key(k) and all_opt[k].has_key("longopt"):
+			if all_opt[k]["getopt"].endswith(":"):
+				longopt_list.append(all_opt[k]["longopt"] + "=")
+			else:
+				longopt_list.append(all_opt[k]["longopt"])
+
+	return (getopt_string, longopt_list)
+
+def _parse_input_stdin(avail_opt):
+	opt = {}
+	name = ""
+	for line in sys.stdin.readlines():
+		line = line.strip()
+		if (line.startswith("#")) or (len(line) == 0):
+			continue
+
+		(name, value) = (line + "=").split("=", 1)
+		value = value[:-1]
+
+		if avail_opt.count(name) == 0 and name in ["nodename"]:
+			continue
+		elif avail_opt.count(name) == 0:
+			logging.warning("Parse error: Ignoring unknown option '%s'\n", line)
+			continue
+
+		if all_opt[name]["getopt"].endswith(":"):
+			opt["--"+all_opt[name]["longopt"].rstrip(":")] = value
+		elif value.lower() in ["1", "yes", "on", "true"]:
+			opt["--"+all_opt[name]["longopt"]] = "1"
+	return opt
+
+def _parse_input_cmdline(avail_opt):
+	filtered_opts = {}
+	_verify_unique_getopt(avail_opt)
+	(getopt_string, longopt_list) = _prepare_getopt_args(avail_opt)
+
+	try:
+		entered_opt = getopt.gnu_getopt(sys.argv[1:], getopt_string, longopt_list)[0]
+	except getopt.GetoptError, error:
+		fail_usage("Parse error: " + error.msg)
+
+	for opt in avail_opt:
+		filtered_opts.update({opt : all_opt[opt]})
+
+	# Short and long getopt names are changed to consistent "--" + long name (e.g. --username)
+	long_opts = {}
+	for arg_name in dict(entered_opt).keys():
+		all_key = [key for (key, value) in filtered_opts.items() \
+			if "--" + value.get("longopt", "") == arg_name or "-" + value.get("getopt", "").rstrip(":") == arg_name][0]
+		long_opts["--" + filtered_opts[all_key]["longopt"]] = dict(entered_opt)[arg_name]
+
+	return long_opts
+
+# for ["John", "Mary", "Eli"] returns "John, Mary and Eli"
+def _join2(words, normal_separator=", ", last_separator=" and "):
+	if len(words) <= 1:
+		return "".join(words)
+	else:
+		return last_separator.join([normal_separator.join(words[:-1]), words[-1]])
+
+def _join_wrap(words, normal_separator=", ", last_separator=" and "):
+	x = _join2(words, normal_separator, last_separator)
+	wrapper = textwrap.TextWrapper()
+	wrapper.initial_indent = " "*42
+	wrapper.subsequent_indent = " "*40
+	wrapper.width = 80
+	wrapper.break_on_hyphens = False
+	wrapper.break_long_words = False
+	wrapped_text = ""
+	for line in wrapper.wrap(x):
+		wrapped_text += line + "\n"
+	return wrapped_text.lstrip().rstrip("\n")
+
+def _get_opts_with_invalid_choices(options):
+	options_failed = []
+	device_opt = options["device_opt"]
+
+	for opt in device_opt:
+		if all_opt[opt].has_key("choices"):
+			longopt = "--" + all_opt[opt]["longopt"]
+			possible_values_upper = [y.upper() for y in all_opt[opt]["choices"]]
+			if options.has_key(longopt):
+				options[longopt] = options[longopt].upper()
+				if not options["--" + all_opt[opt]["longopt"]] in possible_values_upper:
+					options_failed.append(opt)
+	return options_failed
+
+def _verify_unique_getopt(avail_opt):
+	used_getopt = set()
+
+	for opt in avail_opt:
+		getopt_value = all_opt[opt].get("getopt", "").rstrip(":")
+		if getopt_value and getopt_value in used_getopt:
+			fail_usage("Short getopt for %s (-%s) is not unique" % (opt, getopt_value))
+		else:
+			used_getopt.add(getopt_value)
+
+def _get_available_actions(device_opt):
+	available_actions = ["on", "off", "reboot", "status", "list", "list-status", \
+		"monitor", "metadata", "validate-all"]
+	default_value = "reboot"
+
+	if device_opt.count("fabric_fencing"):
+		available_actions.remove("reboot")
+		default_value = "off"
+	if device_opt.count("no_status"):
+		available_actions.remove("status")
+	if not device_opt.count("separator"):
+		available_actions.remove("list")
+		available_actions.remove("list-status")
+
+	return (available_actions, default_value)
diff --git a/fence/agents/lib/fencing_snmp.py.py b/fence/agents/lib/fencing_snmp.py.py
index 0112494..88700c4 100644
--- a/fence/agents/lib/fencing_snmp.py.py
+++ b/fence/agents/lib/fencing_snmp.py.py
@@ -1,9 +1,13 @@
-#!/usr/bin/python
+#!/usr/bin/python -tt
 
 # For example of use please see fence_cisco_mds
 
 import re, pexpect
+import logging
 from fencing import *
+from fencing import fail, fail_usage, EC_TIMED_OUT, run_delay
+
+__all__ = ['FencingSnmp']
 
 ## do not add code here.
 #BEGIN_VERSION_GENERATION
@@ -12,27 +16,22 @@ REDHAT_COPYRIGHT = ""
 BUILD_DATE = ""
 #END_VERSION_GENERATION
 
-# Fix for RHBZ#527844
-def snmp_define_defaults ():
-	all_opt["ipport"]["default"] = "161"
-
 class FencingSnmp:
 	def __init__(self, options):
 		self.options = options
-
-	# Log message if user set verbose option
-	def log_command(self, message):
-		if self.options["log"] >= LOG_MODE_VERBOSE:
-			self.options["debug_fh"].write(message+"\n")
+		run_delay(options)
 
 	def quote_for_run(self, string):
-		return ''.join(map(lambda x:x==r"'" and "'\\''" or x, string))
+		return string.replace(r"'", "'\\''")
 
 	def complete_missed_params(self):
-		mapping = [
-			[['snmp-priv-passwd','password','!snmp-sec-level'],'self.options["--snmp-sec-level"]="authPriv"'],
-			[['!snmp-version','community','!username','!snmp-priv-passwd','!password'],'self.options["--snmp-version"]="2c"']
-			]
+		mapping = [[
+					['snmp-priv-passwd', 'password', '!snmp-sec-level'],
+					'self.options["--snmp-sec-level"]="authPriv"'
+				], [
+					['!snmp-version', 'community', '!username', '!snmp-priv-passwd', '!password'],
+					'self.options["--snmp-version"]="2c"'
+				]]
 
 		for val in mapping:
 			e = val[0]
@@ -40,11 +39,11 @@ class FencingSnmp:
 			res = True
 
 			for item in e:
-				if ((item[0]=='!') and (self.options.has_key("--"+item[1:]))):
+				if item[0] == '!' and self.options.has_key("--" + item[1:]):
 					res = False
 					break
 
-				if ((item[0]!='!') and (not self.options.has_key("--"+item[0:]))):
+				if item[0] != '!' and not self.options.has_key("--" + item[0:]):
 					res = False
 					break
 
@@ -52,50 +51,53 @@ class FencingSnmp:
 				exec(val[1])
 
 	def prepare_cmd(self, command):
-		cmd = "@SNMPBIN@/%s -m '' -Oeqn "% (command)
+		cmd = "%s -m '' -Oeqn "% (command)
 
 		self.complete_missed_params()
 
 		#mapping from our option to snmpcmd option
-		mapping = (('snmp-version', 'v'),('community', 'c'))
+		mapping = (('snmp-version', 'v'), ('community', 'c'))
 
 		for item in mapping:
-			if (self.options.has_key("--" + item[0])):
+			if self.options.has_key("--" + item[0]):
 				cmd += " -%s '%s'"% (item[1], self.quote_for_run(self.options["--" + item[0]]))
 
 		# Some options make sense only for v3 (and for v1/2c can cause "problems")
 		if (self.options.has_key("--snmp-version")) and (self.options["--snmp-version"] == "3"):
 			# Mapping from our options to snmpcmd options for v3
-			mapping_v3 = (('snmp-auth-prot','a'), ('snmp-sec-level','l'), ('snmp-priv-prot','x'), \
-				('snmp-priv-passwd','X'),('password','A'),('username','u'))
+			mapping_v3 = (('snmp-auth-prot', 'a'), ('snmp-sec-level', 'l'), ('snmp-priv-prot', 'x'), \
+				('snmp-priv-passwd', 'X'), ('password', 'A'), ('username', 'u'))
 			for item in mapping_v3:
-				if (self.options.has_key("--"+item[0])):
+				if self.options.has_key("--"+item[0]):
 					cmd += " -%s '%s'"% (item[1], self.quote_for_run(self.options["--" + item[0]]))
 
 		force_ipvx = ""
 
-		if (self.options.has_key("--inet6-only")):
+		if self.options.has_key("--inet6-only"):
 			force_ipvx = "udp6:"
 
-		if (self.options.has_key("--inet4-only")):
+		if self.options.has_key("--inet4-only"):
 			force_ipvx = "udp:"
 
 		cmd += " '%s%s%s'"% (force_ipvx, self.quote_for_run(self.options["--ip"]),
-				self.options.has_key("--ipport") and self.quote_for_run(":" + str (self.options["--ipport"])) or "")
+				self.options.has_key("--ipport") and self.quote_for_run(":" + str(self.options["--ipport"])) or "")
 		return cmd
 
 	def run_command(self, command, additional_timemout=0):
 		try:
-			self.log_command(command)
+			logging.debug("%s\n", command)
 
-			(res_output, res_code) = pexpect.run(command, int(self.options["--shell-timeout"]) + int(self.options["--login-timeout"]) + additional_timemout, True)
+			(res_output, res_code) = pexpect.run(command,
+					int(self.options["--shell-timeout"]) +
+					int(self.options["--login-timeout"]) +
+					additional_timemout, True)
 
-			if (res_code==None):
+			if res_code == None:
 				fail(EC_TIMED_OUT)
 
-			self.log_command(res_output)
+			logging.debug("%s\n", res_output)
 
-			if (res_code!=0) or (re.search("^Error ", res_output, re.MULTILINE) != None):
+			if (res_code != 0) or (re.search("^Error ", res_output, re.MULTILINE) != None):
 				fail_usage("Returned %d: %s"% (res_code, res_output))
 		except pexpect.ExceptionPexpect:
 			fail_usage("Cannot run command %s"%(command))
@@ -103,7 +105,7 @@ class FencingSnmp:
 		return res_output
 
 	def get(self, oid, additional_timemout=0):
-		cmd = "%s '%s'"% (self.prepare_cmd("snmpget"), self.quote_for_run(oid))
+		cmd = "%s '%s'"% (self.prepare_cmd(self.options["--snmpget-path"]), self.quote_for_run(oid))
 
 		output = self.run_command(cmd, additional_timemout).splitlines()
 
@@ -115,17 +117,18 @@ class FencingSnmp:
 		type_of_value = ''
 
 		for item in mapping:
-			if (isinstance(value, item[0])):
+			if isinstance(value, item[0]):
 				type_of_value = item[1]
 				break
 
-		cmd = "%s '%s' %s '%s'"% (self.prepare_cmd("snmpset"), self.quote_for_run(oid), type_of_value, self.quote_for_run(str(value)))
+		cmd = "%s '%s' %s '%s'" % (self.prepare_cmd(self.options["--snmpset-path"]),
+				self.quote_for_run(oid), type_of_value, self.quote_for_run(str(value)))
 
 		self.run_command(cmd, additional_timemout)
 
 	def walk(self, oid, additional_timemout=0):
-		cmd = "%s '%s'"% (self.prepare_cmd("snmpwalk"), self.quote_for_run(oid))
+		cmd = "%s '%s'"% (self.prepare_cmd(self.options["--snmpwalk-path"]), self.quote_for_run(oid))
 
 		output = self.run_command(cmd, additional_timemout).splitlines()
 
-		return map(lambda x:x.split(None, 1), filter(lambda y:len(y)>0 and y[0]=='.', output))
+		return [x.split(None, 1) for x in output if x.startswith(".")]
diff --git a/fence/agents/lib/tests/test_fencing.py b/fence/agents/lib/tests/test_fencing.py
new file mode 100644
index 0000000..f8e421d
--- /dev/null
+++ b/fence/agents/lib/tests/test_fencing.py
@@ -0,0 +1,123 @@
+#!/usr/bin/python
+
+import unittest
+import sys
+sys.path.append("..")
+import fencing
+import copy
+
+class Test_join2(unittest.TestCase):
+	def test_single(self):
+		words = ["Mike"]
+		self.assertEqual(fencing._join2(words), "Mike")
+		self.assertEqual(fencing._join2(words, last_separator=" xor "), "Mike")
+		self.assertEqual(fencing._join2(words, normal_separator=" xor "), "Mike")
+
+	def test_double(self):
+		words = ["Mike", "John"]
+		self.assertEqual(fencing._join2(words), "Mike and John")
+		self.assertEqual(fencing._join2(words, last_separator=" xor "), "Mike xor John")
+		self.assertEqual(fencing._join2(words, normal_separator=" xor "), "Mike and John")
+
+	def test_triple(self):
+		words = ["Mike", "John", "Adam"]
+		self.assertEqual(fencing._join2(words), "Mike, John and Adam")
+		self.assertEqual(fencing._join2(words, last_separator=" xor "), "Mike, John xor Adam")
+		self.assertEqual(fencing._join2(words, normal_separator=" xor "), "Mike xor John and Adam")
+
+	def test_quadruple(self):
+		words = ["Eve", "Mike", "John", "Adam"]
+		self.assertEqual(fencing._join2(words), "Eve, Mike, John and Adam")
+		self.assertEqual(fencing._join2(words, last_separator=" xor "), "Eve, Mike, John xor Adam")
+		self.assertEqual(fencing._join2(words, normal_separator=" xor "), "Eve xor Mike xor John and Adam")
+
+class Test_add_dependency_options(unittest.TestCase):
+	basic_set = fencing.DEPENDENCY_OPT["default"]
+
+	def test_add_nothing(self):
+		self.assertEqual(set(fencing._add_dependency_options([])), set(self.basic_set))
+		self.assertEqual(set(fencing._add_dependency_options(["not-exist"])), set(self.basic_set))
+
+	def test_add_single(self):
+		self.assertEqual(set(fencing._add_dependency_options(["passwd"])), set(self.basic_set + ["passwd_script"]))
+
+	def test_add_tuple(self):
+		self.assertEqual(set(fencing._add_dependency_options(["ssl", "passwd"])), \
+			set(self.basic_set + ["passwd_script", "ssl_secure", "ssl_insecure", "gnutlscli_path"]))
+
+class Test_set_default_values(unittest.TestCase):
+	original_all_opt = None
+
+	def setUp(self):
+		# all_opt[*]["default"] can be changed during tests
+		self.original_all_opt = copy.deepcopy(fencing.all_opt)
+
+	def tearDown(self):
+		fencing.all_opt = copy.deepcopy(self.original_all_opt)
+
+	def _prepare_options(self, device_opts, args = {}):
+		device_opts = fencing._add_dependency_options(device_opts) + device_opts
+
+		arg_opts = args
+		options = dict(arg_opts)
+		options["device_opt"] = device_opts
+		fencing._update_metadata(options)
+		return fencing._set_default_values(options)
+
+	def test_status_io(self):
+		options = self._prepare_options([])
+
+		self.assertEquals(options["--action"], "reboot")
+		self.assertIsNone(options.get("--not-exist", None))
+
+	def test_status_fabric(self):
+		options = self._prepare_options(["fabric_fencing"])
+		self.assertEquals(options["--action"], "off")
+
+	def test_ipport_nothing(self):
+		# should fail because connection method (telnet/ssh/...) is not set at all
+		self.assertRaises(IndexError, self._prepare_options, ["ipaddr"])
+
+	def test_ipport_set(self):
+		options = self._prepare_options(["ipaddr", "telnet"], {"--ipport" : "999"})
+		self.assertEquals(options["--ipport"], "999")
+
+	def test_ipport_telnet(self):
+		options = self._prepare_options(["ipaddr", "telnet"])
+		self.assertEquals(options["--ipport"], "23")
+
+	def test_ipport_ssh(self):
+		options = self._prepare_options(["ipaddr", "secure"], {"--ssh" : "1"})
+		self.assertEquals(options["--ipport"], "22")
+
+	def test_ipport_sshtelnet_use_telnet(self):
+		options = self._prepare_options(["ipaddr", "secure", "telnet"])
+		self.assertEquals(options["--ipport"], "23")
+
+	def test_ipport_sshtelnet_use_ssh(self):
+		options = self._prepare_options(["ipaddr", "secure", "telnet"], {"--ssh" : "1"})
+		self.assertEquals(options["--ipport"], "22")
+
+	def test_ipport_ssl(self):
+		options = self._prepare_options(["ipaddr", "ssl"], {"--ssl-secure" : "1"})
+		self.assertEquals(options["--ipport"], "443")
+
+	def test_ipport_ssl_insecure_as_default(self):
+		fencing.all_opt["ssl_insecure"]["default"] = "1"
+		options = self._prepare_options(["ipaddr", "ssl"])
+		self.assertEquals(options["--ipport"], "443")
+
+	def test_ipport_snmp(self):
+		options = self._prepare_options(["ipaddr", "community"])
+		self.assertEquals(options["--ipport"], "161")
+
+	def test_ipport_web(self):
+		options = self._prepare_options(["ipaddr", "web", "ssl"])
+		self.assertEquals(options["--ipport"], "80")
+
+	def test_path_telnet(self):
+		options = self._prepare_options(["ipaddr", "telnet"])
+		self.assertTrue("--telnet-path" in options)
+
+if __name__ == '__main__':
+	unittest.main()
diff --git a/fence/agents/lib/transfer.py b/fence/agents/lib/transfer.py
deleted file mode 100755
index ddf2486..0000000
--- a/fence/agents/lib/transfer.py
+++ /dev/null
@@ -1,16 +0,0 @@
-#!/usr/bin/python
-
-from fencing import *
-
-def main():
-	for key in all_opt.keys():
-		if all_opt[key].has_key("getopt") and all_opt[key].has_key("longopt"):
-			print "s/options\[\"-" + all_opt[key]["getopt"].rstrip(":") + "\"\]/options[\"--" + \
-				all_opt[key]["longopt"] + "\"]/g"
-			print "s/options.has_key(\"-" + all_opt[key]["getopt"].rstrip(":") + "\")/options.has_key(" + \
-				"\"--" + all_opt[key]["longopt"] + "\")/g"
-
-
-
-if __name__ == "__main__":
-	main()
\ No newline at end of file
diff --git a/fence/agents/lpar/Makefile.am b/fence/agents/lpar/Makefile.am
index 2af387c..ae4fb5e 100644
--- a/fence/agents/lpar/Makefile.am
+++ b/fence/agents/lpar/Makefile.am
@@ -10,8 +10,8 @@ sbin_SCRIPTS		= $(TARGET)
 
 man_MANS		= $(TARGET).8
 
+FENCE_TEST_ARGS         = -l test -p test -a test -n 1 --managed 1
+
 include $(top_srcdir)/make/fencebuild.mk
 include $(top_srcdir)/make/fenceman.mk
-
-clean-local: clean-man
-	rm -f $(TARGET)
+include $(top_srcdir)/make/agentpycheck.mk
diff --git a/fence/agents/lpar/fence_lpar.py b/fence/agents/lpar/fence_lpar.py
index 1d7e09c..2af3bd6 100644
--- a/fence/agents/lpar/fence_lpar.py
+++ b/fence/agents/lpar/fence_lpar.py
@@ -1,18 +1,20 @@
-#!/usr/bin/python
+#!/usr/bin/python -tt
 
 #####
 ##
 ## The Following Agent Has Been Tested On:
 ##
-##  Version       
+##  Version
 ## +---------------------------------------------+
 ##  Tested on HMC
 ##
 #####
 
-import sys, re, pexpect, exceptions
+import sys, re
+import atexit
 sys.path.append("@FENCEAGENTSLIBDIR@")
 from fencing import *
+from fencing import fail, fail_usage, EC_STATUS_HMC
 
 #BEGIN_VERSION_GENERATION
 RELEASE_VERSION=""
@@ -23,17 +25,19 @@ BUILD_DATE=""
 def get_power_status(conn, options):
 	if options["--hmc-version"] == "3":
 		conn.send("lssyscfg -r lpar -m " + options["--managed"] + " -n " + options["--plug"] + " -F name,state\n")
-		conn.log_expect(options, options["--command-prompt"], int(options["--power-timeout"]))
+		conn.log_expect(options["--command-prompt"], int(options["--power-timeout"]))
 
 		try:
-			status = re.compile("^" + options["--plug"] + ",(.*?),.*$", re.IGNORECASE | re.MULTILINE).search(conn.before).group(1)
+			status = re.compile("^" + options["--plug"] + ",(.*?),.*$",
+					re.IGNORECASE | re.MULTILINE).search(conn.before).group(1)
 		except AttributeError:
 			fail(EC_STATUS_HMC)
 	elif options["--hmc-version"] == "4":
-		conn.send("lssyscfg -r lpar -m "+ options["--managed"] +" --filter 'lpar_names=" + options["--plug"] + "'\n")
-		conn.log_expect(options, options["--command-prompt"], int(options["--power-timeout"]))
+		conn.send("lssyscfg -r lpar -m "+ options["--managed"] +
+				" --filter 'lpar_names=" + options["--plug"] + "'\n")
+		conn.log_expect(options["--command-prompt"], int(options["--power-timeout"]))
 
-		try:				
+		try:
 			status = re.compile(",state=(.*?),", re.IGNORECASE).search(conn.before).group(1)
 		except AttributeError:
 			fail(EC_STATUS_HMC)
@@ -51,24 +55,24 @@ def set_power_status(conn, options):
 	if options["--hmc-version"] == "3":
 		conn.send("chsysstate -o " + options["--action"] + " -r lpar -m " + options["--managed"]
 			+ " -n " + options["--plug"] + "\n")
-		conn.log_expect(options, options["--command-prompt"], int(options["--power-timeout"]))
+		conn.log_expect(options["--command-prompt"], int(options["--power-timeout"]))
 	elif options["--hmc-version"] == "4":
 		if options["--action"] == "on":
-			conn.send("chsysstate -o on -r lpar -m " + options["--managed"] + 
-				" -n " + options["--plug"] + 
+			conn.send("chsysstate -o on -r lpar -m " + options["--managed"] +
+				" -n " + options["--plug"] +
 				" -f `lssyscfg -r lpar -F curr_profile " +
 				" -m " + options["--managed"] +
-				" --filter \"lpar_names="+ options["--plug"] +"\"`\n" )
+				" --filter \"lpar_names=" + options["--plug"] + "\"`\n")
 		else:
 			conn.send("chsysstate -o shutdown -r lpar --immed" +
-				" -m " + options["--managed"] + " -n " + options["--plug"] + "\n")		
-		conn.log_expect(options, options["--command-prompt"], int(options["--power-timeout"]))
+				" -m " + options["--managed"] + " -n " + options["--plug"] + "\n")
+		conn.log_expect(options["--command-prompt"], int(options["--power-timeout"]))
 
 def get_lpar_list(conn, options):
-	outlets = { }
+	outlets = {}
 	if options["--hmc-version"] == "3":
 		conn.send("query_partition_names -m " + options["--managed"] + "\n")
-		conn.log_expect(options, options["--command-prompt"], int(options["--power-timeout"]))
+		conn.log_expect(options["--command-prompt"], int(options["--power-timeout"]))
 
 		## We have to remove first 3 lines (command + header) and last line (part of new prompt)
 		####
@@ -76,14 +80,14 @@ def get_lpar_list(conn, options):
 
 		if res == None:
 			fail_usage("Unable to parse output of list command")
-		
+
 		lines = res.group(2).split("\n")
 		for outlet_line in lines:
 			outlets[outlet_line.rstrip()] = ("", "")
 	elif options["--hmc-version"] == "4":
-		conn.send("lssyscfg -r lpar -m " + options["--managed"] + 
+		conn.send("lssyscfg -r lpar -m " + options["--managed"] +
 			" -F name:state\n")
-		conn.log_expect(options, options["--command-prompt"], int(options["--power-timeout"]))
+		conn.log_expect(options["--command-prompt"], int(options["--power-timeout"]))
 
 		## We have to remove first line (command) and last line (part of new prompt)
 		####
@@ -91,7 +95,7 @@ def get_lpar_list(conn, options):
 
 		if res == None:
 			fail_usage("Unable to parse output of list command")
-		
+
 		lines = res.group(1).split("\n")
 		for outlet_line in lines:
 			(port, status) = outlet_line.split(":")
@@ -106,20 +110,20 @@ def define_new_opts():
 		"help" : "-s, --managed=[id]             Name of the managed system",
 		"required" : "0",
 		"shortdesc" : "Managed system name",
-		"order" : 1 }
+		"order" : 1}
 	all_opt["hmc_version"] = {
 		"getopt" : "H:",
 		"longopt" : "hmc-version",
 		"help" : "-H, --hmc-version=[version]    Force HMC version to use: 3, 4 (default)",
 		"required" : "0",
 		"shortdesc" : "Force HMC version to use (3 or 4)",
-		"default" : "4", 
-		"choices" : [ "3", "4" ],
-		"order" : 1 }
+		"default" : "4",
+		"choices" : ["3", "4"],
+		"order" : 1}
 
 def main():
-	device_opt = [  "ipaddr", "login", "passwd", "secure", "cmd_prompt", \
-	                "port", "managed", "hmc_version" ]
+	device_opt = ["ipaddr", "login", "passwd", "secure", "cmd_prompt", \
+	                "port", "managed", "hmc_version"]
 
 	atexit.register(atexit_handler)
 
@@ -127,34 +131,29 @@ def main():
 
 	all_opt["login_timeout"]["default"] = "15"
 	all_opt["secure"]["default"] = "1"
-	all_opt["cmd_prompt"]["default"] = [ ":~>", "]\$", "\$ " ]
+	all_opt["cmd_prompt"]["default"] = [r":~>", r"]\$", r"\$ "]
 
-	options = check_input(device_opt, process_input(device_opt))
+	options = check_input(device_opt, process_input(device_opt), other_conditions = True)
 
-	docs = { }
+	docs = {}
 	docs["shortdesc"] = "Fence agent for IBM LPAR"
 	docs["longdesc"] = ""
 	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")
 
+        if options["--action"] == "validate-all":
+                sys.exit(0)
+
 	##
 	## Operate the fencing device
 	####
 	conn = fence_login(options)
 	result = fence_action(conn, options, set_power_status, get_power_status, get_lpar_list)
-
-	##
-	## Logout from system
-	######
-	try:
-		conn.send("quit\r\n")
-		conn.close()
-	except:
-		pass
-
+	fence_logout(conn, "quit\r\n")
 	sys.exit(result)
+
 if __name__ == "__main__":
 	main()
diff --git a/fence/agents/mcdata/Makefile.am b/fence/agents/mcdata/Makefile.am
deleted file mode 100644
index 54b64fc..0000000
--- a/fence/agents/mcdata/Makefile.am
+++ /dev/null
@@ -1,17 +0,0 @@
-MAINTAINERCLEANFILES	= Makefile.in
-
-TARGET			= fence_mcdata
-
-SRC			= $(TARGET).pl
-
-EXTRA_DIST		= $(SRC)
-
-sbin_SCRIPTS		= $(TARGET)
-
-man_MANS		= $(TARGET).8
-
-include $(top_srcdir)/make/fencebuild.mk
-include $(top_srcdir)/make/fencemanperl.mk
-
-clean-local: clean-man
-	rm -f $(TARGET)
diff --git a/fence/agents/mcdata/fence_mcdata.pl b/fence/agents/mcdata/fence_mcdata.pl
deleted file mode 100644
index 3148a99..0000000
--- a/fence/agents/mcdata/fence_mcdata.pl
+++ /dev/null
@@ -1,361 +0,0 @@
-#!/usr/bin/perl
-
-# This works on the following firmware versions:
-#   01.03.00
-#   02.00.00
-#   04.01.00
-#   04.01.02
-
-use Getopt::Std;
-use Net::Telnet ();
-
-my $ME = $0;
-
-END {
-  defined fileno STDOUT or return;
-  close STDOUT and return;
-  warn "$ME: failed to close standard output: $!\n";
-  $? ||= 1;
-}
-
-# Get the program name from $0 and strip directory names
-$_=$0;
-s/.*\///;
-my $pname = $_;
-
-$opt_o = 'disable';        # Default fence action
-
-# WARNING!! Do not add code bewteen "#BEGIN_VERSION_GENERATION" and 
-# "#END_VERSION_GENERATION"  It is generated by the Makefile
-
-#BEGIN_VERSION_GENERATION
-$RELEASE_VERSION="";
-$REDHAT_COPYRIGHT="";
-$BUILD_DATE="";
-#END_VERSION_GENERATION
-
-
-sub usage
-{
-    print "Usage:\n";
-    print "\n";
-    print "$pname [options]\n";
-    print "\n";
-    print "Options:\n";
-    print "  -a <ip>          IP address or hostname of switch\n";
-    print "  -h               usage\n";
-    print "  -l <name>        Login name\n";
-    print "  -n <num>         Port number to disable\n";
-    print "  -o <string>      Action:  disable (default), enable or metadata\n";
-    print "  -p <string>      Password for login\n";
-    print "  -S <path>        Script to run to retrieve login password\n";
-    print "  -q               quiet mode\n";
-    print "  -V               version\n";
-
-    exit 0;
-}
-
-sub fail
-{
-  ($msg) = @_;
-  print $msg."\n" unless defined $opt_q;
-  $t->close if defined $t;
-  exit 1;
-}
-
-sub fail_usage
-{
-  ($msg)=@_;
-  print STDERR $msg."\n" if $msg;
-  print STDERR "Please use '-h' for usage.\n";
-  exit 1;
-}
-
-sub version
-{
-  print "$pname $RELEASE_VERSION $BUILD_DATE\n";
-  print "$REDHAT_COPYRIGHT\n" if ( $REDHAT_COPYRIGHT );
-
-  exit 0;
-}
-
-sub print_metadata
-{
-print '<?xml version="1.0" ?>
-<resource-agent name="fence_mcdata" shortdesc="I/O Fencing agent for McData FC switches" >
-<longdesc>
-fence_mcdata is an I/O Fencing agent which can be used with McData FC switches. It logs into a McData switch via telnet and disables a specified port. Disabling the port which a machine is connected to effectively fences that machine. Lengthy telnet connections to the switch should be avoided while a GFS cluster is running because the connection will block any necessary fencing actions.
-
-After a fence operation has taken place the fenced machine can no longer connect to the McData FC switch.  When the fenced machine is ready to be brought back into the GFS cluster (after reboot) the port on the McData FC switch needs to be enabled. This can be done by running fence_mcdata and specifying the enable action.
-</longdesc>
-<vendor-url>http://www.brocade.com</vendor-url>
-<parameters>
-        <parameter name="action" unique="1" required="1">
-                <getopt mixed="-o [action]" />
-                <content type="string" default="disable" />
-                <shortdesc lang="en">Fencing Action</shortdesc>
-        </parameter>
-        <parameter name="ipaddr" unique="1" required="1">
-                <getopt mixed="-a [ip]" />
-                <content type="string"  />
-                <shortdesc lang="en">IP Address or Hostname</shortdesc>
-        </parameter>
-        <parameter name="login" unique="1" required="1">
-                <getopt mixed="-l [name]" />
-                <content type="string"  />
-                <shortdesc lang="en">Login Name</shortdesc>
-        </parameter>
-        <parameter name="passwd" unique="1" required="0">
-                <getopt mixed="-p [password]" />
-                <content type="string"  />
-                <shortdesc lang="en">Login password or passphrase</shortdesc>
-        </parameter>
-        <parameter name="passwd_script" unique="1" required="0">
-                <getopt mixed="-S [script]" />
-                <content type="string"  />
-                <shortdesc lang="en">Script to retrieve password</shortdesc>
-        </parameter>
-        <parameter name="port" unique="1" required="1">
-                <getopt mixed="-n [id]" />
-                <content type="string"  />
-                <shortdesc lang="en">Physical plug number or name of virtual machine</shortdesc>
-        </parameter>
-        <parameter name="help" unique="1" required="0">
-                <getopt mixed="-h" />           
-                <content type="string"  />
-                <shortdesc lang="en">Display help and exit</shortdesc>                    
-        </parameter>
-</parameters>
-<actions>
-        <action name="enable" />
-        <action name="disable" />
-        <action name="status" />
-        <action name="metadata" />
-</actions>
-</resource-agent>
-';
-}
-
-
-sub get_options_stdin
-{
-    my $opt;
-    my $line = 0;
-    while( defined($in = <>) )
-    {
-        $_ = $in;
-        chomp;
-
-	# strip leading and trailing whitespace
-        s/^\s*//;
-        s/\s*$//;
-
-	# skip comments
-        next if /^#/;
-
-        $line+=1;
-        $opt=$_;
-        next unless $opt;
-
-        ($name,$val)=split /\s*=\s*/, $opt;
-
-        if ( $name eq "" )
-        {  
-           print STDERR "parse error: illegal name in option $line\n";
-           exit 2;
-	}
-	
-        # DO NOTHING -- this field is used by fenced
-	elsif ($name eq "agent" ) { } 
-
-        elsif ($name eq "ipaddr" ) 
-	{
-            $opt_a = $val;
-        } 
-	elsif ($name eq "login" ) 
-	{
-            $opt_l = $val;
-        } 
-        elsif (($name eq "option" ) || ($name eq "action"))
-        {
-            $opt_o = $val;
-        }
-	elsif ($name eq "passwd" ) 
-	{
-            $opt_p = $val;
-        }
-	elsif ($name eq "passwd_script" )
-	{
-		$opt_S = $val;
-	}
-	elsif ($name eq "port" ) 
-	{
-            $opt_n = $val;
-        } 
-    }
-}
-
-sub telnet_error
-{ 
-  fail "failed: telnet returned: ".$t->errmsg;
-}
-
-######################################################################33
-# MAIN
-
-if (@ARGV > 0) {
-   getopts("a:hl:n:o:p:S:qV") || fail_usage ;
-
-   usage if defined $opt_h;
-   version if defined $opt_V;
-
-   fail_usage "Unknown parameter." if (@ARGV > 0);
-
-   if ((defined $opt_o) && ($opt_o =~ /metadata/i)) {
-     print_metadata();
-     exit 0;
-   }
-
-   fail_usage "No '-a' flag specified." unless defined $opt_a;
-   fail_usage "No '-n' flag specified." unless defined $opt_n;
-   fail_usage "No '-l' flag specified." unless defined $opt_l;
-
-   if (defined $opt_S) {
-     $pwd_script_out = `$opt_S`;
-     chomp($pwd_script_out);
-     if ($pwd_script_out) {
-        $opt_p = $pwd_script_out;
-     }
-   }
-
-   fail_usage "No '-p' or '-S' flag specified." unless defined $opt_p;
-   fail_usage "Unrecognised action '$opt_o' for '-o' flag"
-      unless $opt_o =~ /^(disable|enable)$/i;
-
-} else {
-   get_options_stdin();
-
-   if ((defined $opt_o) && ($opt_o =~ /metadata/i)) {
-     print_metadata();
-     exit 0;
-   }
-
-   fail "failed: no IP address" unless defined $opt_a;
-   fail "failed: no plug number" unless defined $opt_n;
-   fail "failed: no login name" unless defined $opt_l;
-
-   if (defined $opt_S) {
-     $pwd_script_out = `$opt_S`;
-     chomp($pwd_script_out);
-     if ($pwd_script_out) {
-        $opt_p = $pwd_script_out;
-     }
-   }
-
-   fail "failed: no password" unless defined $opt_p;
-   fail "failed: unrecognised action: $opt_o"
-      unless $opt_o =~ /^(disable|enable)$/i;
-}
-
-
-my $block=1;
-$_=$opt_o;
-if(/disable/)
-{
-    $block=1
-}
-elsif(/enable/)
-{
-    $block=0
-}
-else
-{
-    fail "failed: unrecognised action: $opt_o"
-}
-
-#
-# Set up and log in
-#
-
-$t = new Net::Telnet;
-
-$t->errmode(\&telnet_error);
-$t->open($opt_a);
-
-$t->waitfor('/sername:/');
-
-# Send Username
-$t->print($opt_l);
-
-# Send Password
-$t->waitfor('/assword:/');
-$t->print($opt_p);
-$t->waitfor('/\>/');
-
-#> # Set switch to comma delimited output
-#> $t->print("commadelim 1");
-#> $t->waitfor('/\>/');
-
-# Block/Unblock the desired port
-$t->print("config port blocked $opt_n $block");
-($text, $match) = $t->waitfor('/\>/');
-
-# Verfiy that the port has been blocked/unblocked
-$t->print("config port show $opt_n");
-($text, $match) = $t->waitfor('/\>/');
-
-# scan the port configurations to make sure that
-# the port is in the state we told it to be in
-#
-# Output from the prvious command will look like:
-# 
-# Root> config port show 0
-#
-# Port Information
-# Port Number:          0
-# Name:                 name
-# Blocked:              true
-# Extended Distance:    false
-# Type:                 gPort
-# 
-my $fail=1;
-
- at lines = split /\n/,$text;
-foreach my $line (@lines)
-{
-   my $field = "";
-   my $b_state = "";
-
-   if ( $line =~ /^(.*):\s*(\S*)/ )
-   {
-      $field = $1;
-      $b_state = $2;
-   }
-   next unless ( $field eq "Blocked" );
-   if ( ($block && $b_state eq "true") ||
-        (!$block && $b_state eq "false") ||
-        ($block && $b_state eq "Blocked") ||
-        (!$block && $b_state eq "Unblocked") )
-   {
-      $fail = 0;
-   }
-   last;
-}
-
-# log out of the switch
-$t->print("logout");
-$t->close();
-
-if($fail)
-{
-   print "failed: unexpected port state\n" unless $opt_q;
-}
-else
-{
-   print "success: port $opt_n ".($block?"disabled":"enabled")."\n" 
-      unless defined $opt_q;
-}
-
-exit $fail;
-
-
diff --git a/fence/agents/apc/Makefile.am b/fence/agents/mpath/Makefile.am
similarity index 68%
copy from fence/agents/apc/Makefile.am
copy to fence/agents/mpath/Makefile.am
index 355c873..fd3d8d2 100644
--- a/fence/agents/apc/Makefile.am
+++ b/fence/agents/mpath/Makefile.am
@@ -1,6 +1,6 @@
 MAINTAINERCLEANFILES	= Makefile.in
 
-TARGET			= fence_apc
+TARGET			= fence_mpath
 
 SRC			= $(TARGET).py
 
@@ -10,8 +10,8 @@ sbin_SCRIPTS		= $(TARGET)
 
 man_MANS		= $(TARGET).8
 
+FENCE_TEST_ARGS         = -k 1
+
 include $(top_srcdir)/make/fencebuild.mk
 include $(top_srcdir)/make/fenceman.mk
-
-clean-local: clean-man
-	rm -f $(TARGET)
+include $(top_srcdir)/make/agentpycheck.mk
diff --git a/fence/agents/mpath/fence_mpath.py b/fence/agents/mpath/fence_mpath.py
new file mode 100644
index 0000000..b2464b0
--- /dev/null
+++ b/fence/agents/mpath/fence_mpath.py
@@ -0,0 +1,247 @@
+#!/usr/bin/python -tt
+
+import sys
+import stat
+import re
+import os
+import logging
+import atexit
+sys.path.append("@FENCEAGENTSLIBDIR@")
+from fencing import fail_usage, run_command, atexit_handler, check_input, process_input, show_docs
+from fencing import fence_action, all_opt, run_delay
+
+#BEGIN_VERSION_GENERATION
+RELEASE_VERSION=""
+REDHAT_COPYRIGHT=""
+BUILD_DATE=""
+#END_VERSION_GENERATION
+
+def get_status(conn, options):
+	del conn
+	status = "off"
+	for dev in options["devices"]:
+		is_block_device(dev)
+		if options["--key"] in get_registration_keys(options, dev):
+			status = "on"
+		else:
+			logging.debug("No registration for key "\
+				+ options["--key"] + " on device " + dev + "\n")
+	return status
+
+
+def set_status(conn, options):
+	del conn
+	count = 0
+	if options["--action"] == "on":
+		for dev in options["devices"]:
+			is_block_device(dev)
+
+			register_dev(options, dev)
+			if options["--key"] not in get_registration_keys(options, dev):
+				count += 1
+				logging.debug("Failed to register key "\
+					+ options["--key"] + "on device " + dev + "\n")
+				continue
+			dev_write(options, dev)
+
+			if get_reservation_key(options, dev) is None \
+			and not reserve_dev(options, dev) \
+			and get_reservation_key(options, dev) is None:
+				count += 1
+				logging.debug("Failed to create reservation (key="\
+					+ options["--key"] + ", device=" + dev + ")\n")
+
+	else:
+		dev_keys = dev_read(options)
+
+		for dev in options["devices"]:
+			is_block_device(dev)
+
+			if options["--key"] in get_registration_keys(options, dev):
+				preempt_abort(options, dev_keys[dev], dev)
+
+		for dev in options["devices"]:
+			if options["--key"] in get_registration_keys(options, dev):
+				count += 1
+				logging.debug("Failed to remove key "\
+					+ options["--key"] + " on device " + dev + "\n")
+				continue
+
+			if not get_reservation_key(options, dev):
+				count += 1
+				logging.debug("No reservation exists on device " + dev + "\n")
+	if count:
+		logging.error("Failed to verify " + str(count) + " device(s)")
+		sys.exit(1)
+
+
+#run command, returns dict, ret["err"] = exit code; ret["out"] = output
+def run_cmd(options, cmd):
+	ret = {}
+
+	if options.has_key("--use-sudo"):
+		prefix = options["--sudo-path"] + " "
+	else:
+		prefix = ""
+
+	(ret["err"], ret["out"], _) = run_command(options, prefix + cmd)
+	ret["out"] = "".join([i for i in ret["out"] if i is not None])
+	return ret
+
+
+# check if device exist and is block device
+def is_block_device(dev):
+	if not os.path.exists(dev):
+		fail_usage("Failed: device \"" + dev + "\" does not exist")
+	if not stat.S_ISBLK(os.stat(dev).st_mode):
+		fail_usage("Failed: device \"" + dev + "\" is not a block device")
+
+# cancel registration
+def preempt_abort(options, host, dev):
+	cmd = options["--mpathpersist-path"] + " -o --preempt-abort --prout-type=5 --param-rk=" + host +" --param-sark=" + options["--key"] +"-d " + dev
+	return not bool(run_cmd(options, cmd)["err"])
+
+def register_dev(options, dev):
+	cmd = options["--mpathpersist-path"] + " -o --register --param-sark=" + options["--key"] + " -d " + dev
+	#cmd return code != 0 but registration can be successful
+	return not bool(run_cmd(options, cmd)["err"])
+
+def reserve_dev(options, dev):
+	cmd = options["--mpathpersist-path"] + " -o --reserv --prout-type=5 --param-rk=" + options["--key"] + " -d " + dev
+	return not bool(run_cmd(options, cmd)["err"])
+
+def get_reservation_key(options, dev):
+	cmd = options["--mpathpersist-path"] + " -i -r -d " + dev
+	out = run_cmd(options, cmd)
+	if out["err"]:
+		fail_usage("Cannot get reservation key")
+	match = re.search(r"\s+key\s*=\s*0x(\S+)\s+", out["out"], re.IGNORECASE)
+	return match.group(1) if match else None
+
+def get_registration_keys(options, dev):
+	keys = []
+	cmd = options["--mpathpersist-path"] + " -i -k -d " + dev
+	out = run_cmd(options, cmd)
+	if out["err"]:
+		fail_usage("Cannot get registration keys")
+	for line in out["out"].split("\n"):
+		match = re.search(r"\s+0x(\S+)\s*", line)
+		if match:
+			keys.append(match.group(1))
+	return keys
+
+def dev_write(options, dev):
+	file_path = options["--store-path"] + "/mpath.devices"
+
+	if not os.path.isdir(os.path.dirname(options["--store-path"])):
+		os.makedirs(os.path.dirname(options["--store-path"]))
+
+	try:
+		store_fh = open(file_path, "a+")
+	except IOError:
+		fail_usage("Failed: Cannot open file \""+ file_path + "\"")
+	out = store_fh.read()
+	if not re.search(r"^" + dev + r"\s+", out):
+		store_fh.write(dev + "\t" + options["--key"] + "\n")
+	store_fh.close()
+
+def dev_read(options):
+	dev_key = {}
+	file_path = options["--store-path"] + "/mpath.devices"
+	try:
+		store_fh = open(file_path, "r")
+	except IOError:
+		fail_usage("Failed: Cannot open file \"" + file_path + "\"")
+	# get not empty lines from file
+	for (device, key) in [line.strip().split() for line in store_fh if line.strip()]:
+		dev_key[device] = key
+	store_fh.close()
+	return dev_key
+
+def define_new_opts():
+	all_opt["devices"] = {
+		"getopt" : "d:",
+		"longopt" : "devices",
+		"help" : "-d, --devices=[devices]        List of devices to use for current operation",
+		"required" : "0",
+		"shortdesc" : "List of devices to use for current operation. Devices can \
+be comma-separated list of device-mapper multipath devices (eg. /dev/dm-3). \
+Each device must support SCSI-3 persistent reservations.",
+		"order": 1
+	}
+	all_opt["key"] = {
+		"getopt" : "k:",
+		"longopt" : "key",
+		"help" : "-k, --key=[key]                Key to use for the current operation",
+		"required" : "1",
+		"shortdesc" : "Key to use for the current operation. This key should be \
+unique to a node and have to be written in /etc/multipath.conf. For the \"on\" action, the key specifies the key use to \
+register the local node. For the \"off\" action, this key specifies the key to \
+be removed from the device(s).",
+		"order": 1
+	}
+	all_opt["mpathpersist_path"] = {
+		"getopt" : ":",
+		"longopt" : "mpathpersist-path",
+		"help" : "--mpathpersist-path=[path]     Path to mpathpersist binary",
+		"required" : "0",
+		"shortdesc" : "Path to mpathpersist binary",
+		"default" : "@MPATH_PATH@",
+		"order": 200
+	}
+	all_opt["store_path"] = {
+		"getopt" : ":",
+		"longopt" : "store-path",
+		"help" : "--store-path=[path]            Path to directory containing cached keys",
+		"required" : "0",
+		"shortdesc" : "Path to directory where fence agent can store information",
+		"default" : "@STORE_PATH@",
+		"order": 200
+	}
+
+def main():
+	atexit.register(atexit_handler)
+
+	device_opt = ["no_login", "no_password", "devices", "key", "sudo", \
+	        "fabric_fencing", "on_target", "store_path", "mpathpersist_path"]
+
+	define_new_opts()
+
+	options = check_input(device_opt, process_input(device_opt), other_conditions=True)
+
+	docs = {}
+	docs["shortdesc"] = "Fence agent for multipath persistent reservation"
+	docs["longdesc"] = "fence_mpath is an I/O fencing agent that uses SCSI-3 \
+persistent reservations to control access multipath devices. Underlying \
+devices must support SCSI-3 persistent reservations (SPC-3 or greater) as \
+well as the \"preempt-and-abort\" subcommand.\nThe fence_mpath agent works by \
+having an unique key for each pair of node and device that has to be set also \
+in /etc/multipath.conf. Once registered, a single node will become the reservation holder \
+by creating a \"write exclusive, registrants only\" reservation on the \
+device(s). The result is that only registered nodes may write to the \
+device(s). When a node failure occurs, the fence_mpath agent will remove the \
+key belonging to the failed node from the device(s). The failed node will no \
+longer be able to write to the device(s). A manual reboot is required."
+	docs["vendorurl"] = "https://www.sourceware.org/dm/"
+	show_docs(options, docs)
+
+	run_delay(options)
+
+	# Input control BEGIN
+	if not "--key" in options:
+		fail_usage("Failed: key is required")
+
+        if options["--action"] == "validate-all":
+                sys.exit(0)
+
+	options["devices"] = options["--devices"].split(",")
+
+	if not options["devices"]:
+		fail_usage("Failed: No devices found")
+	# Input control END
+
+	result = fence_action(None, options, set_status, get_status)
+	sys.exit(result)
+
+if __name__ == "__main__":
+	main()
diff --git a/fence/agents/netio/Makefile.am b/fence/agents/netio/Makefile.am
index 3e1a1d9..8820b8e 100644
--- a/fence/agents/netio/Makefile.am
+++ b/fence/agents/netio/Makefile.am
@@ -10,8 +10,8 @@ sbin_SCRIPTS		= $(TARGET)
 
 man_MANS		= $(TARGET).8
 
+FENCE_TEST_ARGS         = -l test -p test -a test -n 1
+
 include $(top_srcdir)/make/fencebuild.mk
 include $(top_srcdir)/make/fenceman.mk
-
-clean-local: clean-man
-	rm -f $(TARGET)
+include $(top_srcdir)/make/agentpycheck.mk
diff --git a/fence/agents/netio/fence_netio.py b/fence/agents/netio/fence_netio.py
index ffb6e30..7b67e15 100755
--- a/fence/agents/netio/fence_netio.py
+++ b/fence/agents/netio/fence_netio.py
@@ -1,8 +1,10 @@
-#!/usr/bin/python
+#!/usr/bin/python -tt
 
-import sys, re, pexpect, exceptions
+import sys, re, pexpect
+import atexit
 sys.path.append("@FENCEAGENTSLIBDIR@")
 from fencing import *
+from fencing import fspawn, fail, EC_LOGIN_DENIED, run_delay
 
 #BEGIN_VERSION_GENERATION
 RELEASE_VERSION=""
@@ -13,7 +15,7 @@ BUILD_DATE=""
 def get_power_status(conn, options):
 	conn.send_eol("port %s" % options["--plug"])
 	re_status = re.compile("250 [01imt]")
-	conn.log_expect(options, re_status, int(options["--shell-timeout"]))
+	conn.log_expect(re_status, int(options["--shell-timeout"]))
 	status = {
 		"0" : "off",
 		"1" : "on",
@@ -32,7 +34,7 @@ def set_power_status(conn, options):
 	}[options["--action"]]
 
 	conn.send_eol("port %s %s" % (options["--plug"], action))
-	conn.log_expect(options, "250 OK", int(options["--shell-timeout"]))
+	conn.log_expect("250 OK", int(options["--shell-timeout"]))
 
 def get_outlet_list(conn, options):
 	result = {}
@@ -41,7 +43,7 @@ def get_outlet_list(conn, options):
 		# the NETIO-230B has 4 ports, counting start at 1
 		for plug in ["1", "2", "3", "4"]:
 			conn.send_eol("port setup %s" % plug)
-			conn.log_expect(options, "250 .+", int(options["--shell-timeout"]))
+			conn.log_expect("250 .+", int(options["--shell-timeout"]))
 			# the name is enclosed in "", drop those with [1:-1]
 			name = conn.after.split()[1][1:-1]
 			result[plug] = (name, "unknown")
@@ -51,20 +53,17 @@ def get_outlet_list(conn, options):
 	return result
 
 def main():
-	device_opt = [ "ipaddr", "login", "passwd", "port" ]
+	device_opt = ["ipaddr", "login", "passwd", "port", "telnet"]
 
 	atexit.register(atexit_handler)
 
-	opt = process_input(device_opt)
-
-	# set default port for telnet only
-	if 0 == opt.has_key("--ipport"):
-		opt["--ipport"] = "1234"
+	all_opt["ipport"]["default"] = "1234"
 
+	opt = process_input(device_opt)
 	opt["eol"] = "\r\n"
 	options = check_input(device_opt, opt)
 
-	docs = { }
+	docs = {}
 	docs["shortdesc"] = "I/O Fencing agent for Koukaam NETIO-230B"
 	docs["longdesc"] = "fence_netio is an I/O Fencing agent which can be \
 used with the Koukaam NETIO-230B Power Distribution Unit. It logs into \
@@ -78,41 +77,23 @@ block any necessary fencing actions."
 	## Operate the fencing device
 	## We can not use fence_login(), username and passwd are sent on one line
 	####
+	run_delay(options)
 	try:
-		try:
-			conn = fspawn(options, TELNET_PATH)
-			conn.send("set binary\n")
-			conn.send("open %s -%s\n"%(options["--ip"], options["--ipport"]))
-		except pexpect.ExceptionPexpect, ex:
-			sys.stderr.write(str(ex) + "\n")
-			sys.stderr.write("Due to limitations, binary dependencies on fence agents "
-			"are not in the spec file and must be installed separately." + "\n")
-			sys.exit(EC_GENERIC_ERROR)
-
-		screen = conn.read_nonblocking(size=100, timeout=int(options["--shell-timeout"]))
-		conn.log_expect(options, "100 HELLO .*", int(options["--shell-timeout"]))
+		conn = fspawn(options, options["--telnet-path"])
+		conn.send("set binary\n")
+		conn.send("open %s -%s\n"%(options["--ip"], options["--ipport"]))
+
+		conn.read_nonblocking(size=100, timeout=int(options["--shell-timeout"]))
+		conn.log_expect("100 HELLO .*", int(options["--shell-timeout"]))
 		conn.send_eol("login %s %s" % (options["--username"], options["--password"]))
-		conn.log_expect(options, "250 OK", int(options["--shell-timeout"]))
+		conn.log_expect("250 OK", int(options["--shell-timeout"]))
 	except pexpect.EOF:
 		fail(EC_LOGIN_DENIED)
 	except pexpect.TIMEOUT:
 		fail(EC_LOGIN_DENIED)
-	result = fence_action(conn, options, set_power_status, get_power_status, get_outlet_list)
-
-	##
-	## Logout from system
-	##
-	## In some special unspecified cases it is possible that
-	## connection will be closed before we run close(). This is not
-	## a problem because everything is checked before.
-	######
-	try:
-		conn.send("quit\n")
-		conn.log_expect(options, "110 BYE", int(options["--shell-timeout"]))
-		conn.close()
-	except:
-		pass
 
+	result = fence_action(conn, options, set_power_status, get_power_status, get_outlet_list)
+	fence_logout(conn, "quit\n")
 	sys.exit(result)
 
 if __name__ == "__main__":
diff --git a/fence/agents/ovh/Makefile.am b/fence/agents/ovh/Makefile.am
index c6d7d01..3793562 100644
--- a/fence/agents/ovh/Makefile.am
+++ b/fence/agents/ovh/Makefile.am
@@ -10,8 +10,8 @@ sbin_SCRIPTS		= $(TARGET)
 
 man_MANS		= $(TARGET).8
 
+FENCE_TEST_ARGS         = -l test -p test -n 1 --email test at test.te
+
 include $(top_srcdir)/make/fencebuild.mk
 include $(top_srcdir)/make/fenceman.mk
-
-clean-local: clean-man
-	rm -f $(TARGET)
+include $(top_srcdir)/make/agentpycheck.mk
diff --git a/fence/agents/ovh/fence_ovh.py b/fence/agents/ovh/fence_ovh.py
index 2ec3fa0..de5333c 100644
--- a/fence/agents/ovh/fence_ovh.py
+++ b/fence/agents/ovh/fence_ovh.py
@@ -1,4 +1,4 @@
-#!/usr/bin/python
+#!/usr/bin/python -tt
 # Copyright 2013 Adrian Gibanel Lopez (bTactic)
 # Adrian Gibanel improved this script at 2013 to add verification of success and to output metadata
 
@@ -10,14 +10,17 @@
 
 import sys, time
 import shutil, tempfile
+import logging
+import atexit
 from datetime import datetime
 from suds.client import Client
 from suds.xsd.doctor import ImportDoctor, Import
 sys.path.append("@FENCEAGENTSLIBDIR@")
 from fencing import *
+from fencing import fail, fail_usage, EC_LOGIN_DENIED, run_delay
 
 OVH_RESCUE_PRO_NETBOOT_ID = '28'
-OVH_HARD_DISK_NETBOOT_ID  = '1'
+OVH_HARD_DISK_NETBOOT_ID = '1'
 
 STATUS_HARD_DISK_SLEEP = 240 # Wait 4 minutes to SO to boot
 STATUS_RESCUE_PRO_SLEEP = 150 # Wait 2 minutes 30 seconds to Rescue-Pro to run
@@ -26,34 +29,28 @@ def define_new_opts():
 	all_opt["email"] = {
 		"getopt" : "Z:",
 		"longopt" : "email",
-		"help" : "-Z, --email=<email>          email for reboot message: admin at domain.com",
+		"help" : "-Z, --email=[email]          email for reboot message: admin at domain.com",
 		"required" : "1",
 		"shortdesc" : "Reboot email",
-		"default" : "",
-		"order" : 1 }
-
-def netboot_reboot(options, mode):
-	conn = soap_login(options)
+		"order" : 1}
 
+def netboot_reboot(conn, options, mode):
 	# dedicatedNetbootModifyById changes the mode of the next reboot
 	conn.service.dedicatedNetbootModifyById(options["session"], options["--plug"], mode, '', options["--email"])
- 
+
 	# dedicatedHardRebootDo initiates a hard reboot on the given node
-	conn.service.dedicatedHardRebootDo(options["session"], options["--plug"], 'Fencing initiated by cluster', '', 'en')
+	conn.service.dedicatedHardRebootDo(options["session"],
+			options["--plug"], 'Fencing initiated by cluster', '', 'en')
 
 	conn.logout(options["session"])
 
-def reboot_time(options):
-	conn = soap_login(options)
-
+def reboot_time(conn, options):
 	result = conn.service.dedicatedHardRebootStatus(options["session"], options["--plug"])
-	tmpstart = datetime.strptime(result.start,'%Y-%m-%d %H:%M:%S')
-	tmpend = datetime.strptime(result.end,'%Y-%m-%d %H:%M:%S')
+	tmpstart = datetime.strptime(result.start, '%Y-%m-%d %H:%M:%S')
+	tmpend = datetime.strptime(result.end, '%Y-%m-%d %H:%M:%S')
 	result.start = tmpstart
 	result.end = tmpend
 
-	conn.logout(options["session"])
-
 	return result
 
 def soap_login(options):
@@ -69,24 +66,24 @@ def soap_login(options):
 	try:
 		soap = Client(url, doctor=d)
 		session = soap.service.login(options["--username"], options["--password"], 'en', 0)
-	except Exception, ex:
-		fail(EC_LOGIN_DENIED)   
+	except Exception:
+		fail(EC_LOGIN_DENIED)
 
 	options["session"] = session
 	return soap
 
 def remove_tmp_dir(tmp_dir):
 	shutil.rmtree(tmp_dir)
-	
+
 def main():
-	device_opt = [ "login", "passwd", "port", "email" ]
+	device_opt = ["login", "passwd", "port", "email", "no_status", "web"]
 
 	atexit.register(atexit_handler)
 
 	define_new_opts()
-	options = check_input(device_opt, process_input(device_opt))
+	options = check_input(device_opt, process_input(device_opt), other_conditions=True)
 
-	docs = { }
+	docs = {}
 	docs["shortdesc"] = "Fence agent for OVH"
 	docs["longdesc"] = "fence_ovh is an Power Fencing agent \
 which can be used within OVH datecentre. \
@@ -95,50 +92,72 @@ Poweroff is simulated with a reboot into rescue-pro mode."
 	docs["vendorurl"] = "http://www.ovh.net"
 	show_docs(options, docs)
 
-	if options["--action"] in [ "list", "status"]:
-		fail_usage("Action '" + options["--action"] + "' is not supported in this fence agent")
+	if options["--action"] == "list":
+		fail_usage("Action 'list' is not supported in this fence agent")
 
-	if options["--plug"].endswith(".ovh.net") == False:
-		options["--plug"] += ".ovh.net"
+	if options["--action"] == "list-status":
+		fail_usage("Action 'list-status' is not supported in this fence agent")
 
-	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")
 
+	if options["--action"] == "validate-all":
+		sys.exit(0)
+
+	if options["--action"] != "monitor" and not options["--plug"].endswith(".ovh.net"):
+		options["--plug"] += ".ovh.net"
+
+	run_delay(options)
+
+	conn = soap_login(options)
+
+	if options["--action"] == 'monitor':
+		try:
+			conn.service.logout(options["session"])
+		except Exception:
+			pass
+		sys.exit(0)
+
 	# Save datetime just before changing netboot
 	before_netboot_reboot = datetime.now()
 
 	if options["--action"] == 'off':
 		# Reboot in Rescue-pro
-		netboot_reboot(options,OVH_RESCUE_PRO_NETBOOT_ID)
+		netboot_reboot(conn, options, OVH_RESCUE_PRO_NETBOOT_ID)
 		time.sleep(STATUS_RESCUE_PRO_SLEEP)
-	elif options["--action"] in  ['on', 'reboot' ]:
+	elif options["--action"] in  ['on', 'reboot']:
 		# Reboot from HD
-		netboot_reboot(options,OVH_HARD_DISK_NETBOOT_ID)
+		netboot_reboot(conn, options, OVH_HARD_DISK_NETBOOT_ID)
 		time.sleep(STATUS_HARD_DISK_SLEEP)
 
 	# Save datetime just after reboot
 	after_netboot_reboot = datetime.now()
 
 	# Verify that action was completed sucesfully
-	reboot_t = reboot_time(options)
-
-	if options.has_key("--verbose"):
-		options["debug_fh"].write("reboot_start_end.start: "+ reboot_t.start.strftime('%Y-%m-%d %H:%M:%S')+"\n")         
-		options["debug_fh"].write("before_netboot_reboot: " + before_netboot_reboot.strftime('%Y-%m-%d %H:%M:%S')+"\n")
-		options["debug_fh"].write("reboot_start_end.end: "  + reboot_t.end.strftime('%Y-%m-%d %H:%M:%S')+"\n")        
-		options["debug_fh"].write("after_netboot_reboot: "  + after_netboot_reboot.strftime('%Y-%m-%d %H:%M:%S')+"\n")  
-                
+	reboot_t = reboot_time(conn, options)
+
+	logging.debug("reboot_start_end.start: %s\n",
+		reboot_t.start.strftime('%Y-%m-%d %H:%M:%S'))
+	logging.debug("before_netboot_reboot: %s\n",
+		before_netboot_reboot.strftime('%Y-%m-%d %H:%M:%S'))
+	logging.debug("reboot_start_end.end: %s\n",
+		reboot_t.end.strftime('%Y-%m-%d %H:%M:%S'))
+	logging.debug("after_netboot_reboot: %s\n",
+		after_netboot_reboot.strftime('%Y-%m-%d %H:%M:%S'))
+
 	if reboot_t.start < after_netboot_reboot < reboot_t.end:
 		result = 0
-		if options.has_key("--verbose"):
-			options["debug_fh"].write("Netboot reboot went OK.\n")
+		logging.debug("Netboot reboot went OK.\n")
 	else:
 		result = 1
-		if options.has_key("--verbose"):
-			options["debug_fh"].write("ERROR: Netboot reboot wasn't OK.\n")
+		logging.debug("ERROR: Netboot reboot wasn't OK.\n")
 
-	sys.exit(result)
+	try:
+		conn.service.logout(options["session"])
+	except Exception:
+		pass
 
+	sys.exit(result)
 
 if __name__ == "__main__":
 	main()
diff --git a/fence/agents/apc/Makefile.am b/fence/agents/pve/Makefile.am
similarity index 65%
copy from fence/agents/apc/Makefile.am
copy to fence/agents/pve/Makefile.am
index 355c873..792ec24 100644
--- a/fence/agents/apc/Makefile.am
+++ b/fence/agents/pve/Makefile.am
@@ -1,6 +1,6 @@
 MAINTAINERCLEANFILES	= Makefile.in
 
-TARGET			= fence_apc
+TARGET			= fence_pve
 
 SRC			= $(TARGET).py
 
@@ -10,8 +10,8 @@ sbin_SCRIPTS		= $(TARGET)
 
 man_MANS		= $(TARGET).8
 
+FENCE_TEST_ARGS		= -l test -p test -a test -n 1
+
 include $(top_srcdir)/make/fencebuild.mk
 include $(top_srcdir)/make/fenceman.mk
-
-clean-local: clean-man
-	rm -f $(TARGET)
+include $(top_srcdir)/make/agentpycheck.mk
diff --git a/fence/agents/pve/fence_pve.py b/fence/agents/pve/fence_pve.py
new file mode 100644
index 0000000..bb59a9b
--- /dev/null
+++ b/fence/agents/pve/fence_pve.py
@@ -0,0 +1,183 @@
+#!/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"]))
+	if opt.has_key("--ssl") or opt.has_key("--ssl-secure"):
+		conn.setopt(pycurl.SSL_VERIFYPEER, 1)
+		conn.setopt(pycurl.SSL_VERIFYHOST, 2)
+
+	if opt.has_key("--ssl-insecure"):
+		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 at 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/fence/agents/rackswitch/Makefile.am b/fence/agents/rackswitch/Makefile.am
deleted file mode 100644
index 8c435c0..0000000
--- a/fence/agents/rackswitch/Makefile.am
+++ /dev/null
@@ -1,16 +0,0 @@
-MAINTAINERCLEANFILES	 = Makefile.in
-
-TARGET			 = fence_rackswitch
-
-sbin_PROGRAMS		 = $(TARGET)
-
-noinst_HEADERS		 = do_rack.h
-
-fence_rackswitch_SOURCES = do_rack.c
-
-man_MANS		 = $(TARGET).8
-
-include $(top_srcdir)/make/fencemanc.mk
-
-clean-local: clean-man
-	rm -f $(TARGET)
diff --git a/fence/agents/rackswitch/do_rack.c b/fence/agents/rackswitch/do_rack.c
deleted file mode 100644
index ee29153..0000000
--- a/fence/agents/rackswitch/do_rack.c
+++ /dev/null
@@ -1,807 +0,0 @@
-#include "clusterautoconfig.h"
-
-#include "do_rack.h"
-
-const char *pname = "fence_rack";
-
-int quiet_flag = 0;
-int verbose_flag = 0;
-int debug_flag = 0;
-
-char ipaddr[256];
-char portnumber[256];
-char username[256];
-char password[256];
-char arg[256];
-char name[256];
-char pwd_script[PATH_MAX] = { 0, };
-
-char readbuf[MAXBUF];
-char writebuf[MAXBUF];
-int sock;
-
-char op_login = 0x7e; 	        /* 126*/ 
-char op_action = 0x66;	        /* 102 */
-char ack_login = 0x7D;	        /* 125 */
-
-char action_idle = 0x00;
-char action_reset = 0x01;
-char action_off = 0x02;
-char action_offon = 0x03;
-
-char configuration_request = 0x5b;   /* 91 */
-char config_reply = 0x5c;            /* 92 */
-char config_general = 0x01;
-char config_section1 = 0x02;
-char config_section2 = 0x03;
-char config_section3 = 0x04;
-
-char message_status = 0x65;         /* 101 */
-
-char login_deny = 0xFF;          
-
-int time_out = 60;
-
-void ignore_message_status(void);
-int wait_frame(char);
-
-/*
- * scan input, waiting for a given frame
- */
-int wait_frame(char frame_id)
-{
-  int read_more = 1;
-  int success = 0;
-  int n;
-  char target = frame_id;
-
-  if(debug_flag){printf("%s: Looking for frametype 0x%.2x\n",name,target);}
-  read_more = 1;
-  while(read_more){
-    n = read(sock,readbuf,1);
-    if(debug_flag){printf("%s: Found frametype 0x%.2x\n",name,readbuf[0]);}
-    if(readbuf[0] == target){
-      read_more = 0;
-      success = 1;
-    }
-    else{
-      if(readbuf[0] == message_status){
-	ignore_message_status();
-	read_more = 1;
-      }
-      else{
-	if(debug_flag){printf("%s: Got unexpected frame from switch\n",name);}
-	read_more = 0;
-	success = 0;
-      }
-    }
-  }
-  return(success);
-}  
-
-void ignore_message_status(void)
-{
-  int n,i;
-  int read_more = 1;
-  int number_of_temp;
-  int number_of_config_mobo;
-    
-  if(debug_flag){printf("%s: Ignoring message-status\n",name);}
-  read_more=1;
-  while(read_more){
-    n = read(sock,readbuf,1); /* status */
-    if(n == 1)
-      read_more = 0;
-  }
-
-  read_more = 1;
-  while(read_more){         /* Date & time */
-    n = read(sock,readbuf,1);
-    if(readbuf[0] == '\0'){
-      read_more = 0;
-    }
-    else{
-      read_more = 1;
-    }
-  }
-   
-  read_more = 1;
-  number_of_temp = 0;
-  n = read(sock,readbuf,1); /* Temprature Input count */
-  number_of_temp = (int)readbuf[0];
-  
-  for(i=0;i<number_of_temp;i++){
-    read_more = 1;
-    while(read_more){
-      n = read(sock,readbuf,1); /* Temprature input ID */
-      n = read(sock,readbuf,8); /* Temprature Value, Fahrenheit */
-      n = read(sock,readbuf,8); /* Temprature Vaule, Celcius */
-      n = read(sock,readbuf,1); /* Temprature Alarm */
-    }
-  }
-  number_of_config_mobo = 0;
-  for(i=4;i>0;i--){
-    read_more = 1;	
-    while(read_more){
-      n=read(sock,readbuf,1);
-      if(n == 1){
-	read_more = 0;
-	number_of_config_mobo = number_of_config_mobo + (int)(readbuf[0]<<(8*(i-1)));
-      }
-    }
-  }
-  for(i=0;i<number_of_config_mobo;i++){
-    n = read(sock,readbuf,4); /* Motherboard ID */
-    n = read(sock,readbuf,1); /* Motherboard status */
-  }
-}
-
-
-
-static void print_usage(void)
-{
-  printf("Usage:\n");
-  printf("\n");
-  printf("%s [options]\n"
-         "\n"
-         "Options:\n"
-         "  -h               usage\n"
-	 "  -a <ip>          IP address for RackSwitch\n"
-	 "  -n <dec num>     Physical plug number on RackSwitch\n"
-	 "  -l <string>      Username\n"
-	 "  -p <string>      Password\n"
-	 "  -S <path>        Script to retrieve password\n"
-	 "  -v               Verbose\n"
-	 "  -q               Quiet\n"
-         "  -V               Version information\n", pname);
-}
-
-
-
-static void print_metadata(void)
-{
-  printf("<?xml version=\"1.0\" ?>\n"
-        "<resource-agent name=\"fence_rackswitch\" shortdesc=\"fence_rackswitch - I/O Fencing agent for RackSaver RackSwitch\" >\n"
-        "<longdesc>fence_rackswitch is an I/O Fencing agent which can be used with the RackSaver RackSwitch. It logs into the RackSwitch and boots a specified plug. Using the http interface to the RackSwitch should be avoided while a GFS cluster is running because the connection may interfere with the operation of this agent.</longdesc>\n"
-	"<vendor-url>http://www.bladenetwork.net</vendor-url>\n"
-	"<parameters>\n"
-        "<parameter name=\"ipaddr\" unique=\"1\" required=\"1\">\n"
-        "\t<getopt mixed=\"-a [ip]\" />\n"
-        "\t<content type=\"string\"  />\n"
-        "\t<shortdesc lang=\"en\">IP Address or Hostname</shortdesc>\n"
-        "</parameter>\n"
-        "<parameter name=\"login\" unique=\"1\" required=\"1\">\n"
-        "\t<getopt mixed=\"-l [name]\" />\n"
-        "\t<content type=\"string\"  />\n"
-        "\t<shortdesc lang=\"en\">Login Name</shortdesc>\n"
-        "</parameter>\n"
-        "<parameter name=\"passwd\" unique=\"1\" required=\"0\">\n"
-        "\t<getopt mixed=\"-p [password]\" />\n"
-        "\t<content type=\"string\"  />\n"
-        "\t<shortdesc lang=\"en\">Login password or passphrase</shortdesc>\n"
-        "</parameter>\n"
-        "<parameter name=\"passwd_script\" unique=\"1\" required=\"0\">\n"
-        "\t<getopt mixed=\"-S [script]\" />\n"
-        "\t<content type=\"string\"  />\n"
-        "\t<shortdesc lang=\"en\">Script to retrieve password</shortdesc>\n"
-        "</parameter>\n"
-	"</parameters>\n"
-	"<actions>\n"
-	"\t<action name=\"metadata\" />\n"
-	"</actions>\n"
-	"</resource-agent>\n");
-}
-
-static void get_options(int argc, char **argv)
-{
-  int c;
-  char *value;
-
-  if (argc > 1){  
-    /*
-     * Command line input
-     */
-    while ((c = getopt(argc, argv, "ha:n:l:p:S:vqVdo:")) != -1)
-      {
-	switch(c)
-	  {
-	  case 'h':
-	    print_usage();
-	    exit(DID_SUCCESS);
-	
-	  case 'a':
-	    strncpy(ipaddr,optarg,254);
-	    break;
-
-	  case 'n':
-	    strncpy(portnumber,optarg,254);
-	    break;
-
-	  case 'l':
-	    strncpy(username,optarg,254);	
-	    break;
-
-	  case 'p':
-	    strncpy(password,optarg,254);
-	    break;
-
-	  case 'S':
-		strncpy(pwd_script, optarg, sizeof(pwd_script));
-		pwd_script[sizeof(pwd_script) - 1] = '\0';
-		break;
-
-	  case 'v':
-	    verbose_flag = 1;
-	    break;
-
-	  case 'q':
-	    quiet_flag = 1;
-	    break;
-
-	  case 'd':
-	    debug_flag = 1;
-	    break;
-
-	  case 'V':
-	    printf("%s %s (built %s %s)\n", pname, VERSION,
-		   __DATE__, __TIME__);
-	    printf("%s\n", REDHAT_COPYRIGHT);
-	    exit(DID_SUCCESS);
-	    break;
-
-	  case ':':
-	  case '?':
-	    fprintf(stderr, "Please use '-h' for usage.\n");
-	    exit(DID_FAILURE);
-	    break;
-          
-          case 'o':
-            if (strncasecmp(optarg, "metadata", 254) == 0) {
-              print_metadata();
-              exit(DID_SUCCESS);              
-            } else {
-              fprintf(stderr, "Only 'metadata' option is aviable for this fence agent\n");
-              exit(DID_FAILURE);
-            }
-            break;
-
-	  default:
-	    fprintf(stderr, "Bad programmer! You forgot to catch the %c flag\n", c);
-	    exit(DID_FAILURE);
-	    break;
-
-	  }
-      }
-    strcpy(name, pname);
-  }
-  else{
-    errno = 0;
-    while(fgets(arg, 256, stdin) != NULL){    
- if( (value = strchr(arg, '\n')) == NULL){
-        fprintf(stderr, "line too long: '%s'\n", arg);
-	exit(DID_FAILURE);
-      }
-      *value = 0;
-      if( (value = strchr(arg, '=')) == NULL){
-        /* in this agent we can ignore options without value
-         * as we don't need any of them, here. But we should
-         * accept and ignore them.
-         */
-        fprintf(stderr, "invalid input: '%s'\n", arg);
-        continue;
-      }
-      *value = 0;
-      value++;
-    /*  bahfuck. "agent" is not passed to us anyway
-     *  if (!strcmp(arg, "agent")){
-      *  strcpy(name, value);
-       * pname = name;
-      *}
-      */
-      strcpy(name, pname);
-      if (!strcmp(arg, "ipaddr"))
-        strcpy(ipaddr, value);
-
-      if (!strcmp(arg, "action")) 
-        if (strncasecmp(value, "metadata", 254) == 0) {
-          print_metadata();
-          exit(DID_SUCCESS);              
-        } else {
-          fprintf(stderr, "Only 'metadata' option is aviable for this fence agent\n");
-          exit(DID_FAILURE);
-        } 
-      
-      if (!strcmp(arg, "portnumber"))
-        strcpy(portnumber, value);
-      
-      if (!strcmp(arg, "username"))
-        strcpy(username, value);
-      
-      if (!strcmp(arg, "password"))
-        strcpy(password, value);
-
-	  if (!strcasecmp(arg, "passwd_script")) {
-		strncpy(pwd_script, optarg, sizeof(pwd_script));
-		pwd_script[sizeof(pwd_script) - 1] = '\0';
-	  }
-    }
-    errno = 0;
-    
-  }
-
-  if (pwd_script[0] != '\0') {
-	FILE *fp;
-	char pwd_buf[1024];
-
-	fp = popen(pwd_script, "r");
-	if (fp != NULL) {
-		ssize_t len = fread(pwd_buf, 1, sizeof(pwd_buf), fp);
-		if (len > 0) {
-			char *p;
-			p = strchr(pwd_buf, '\n');
-			if (p != NULL)
-				*p = '\0';
-			p = strchr(pwd_buf, '\r');
-			if (p != NULL)
-				*p = '\0';
-			strncpy(password, pwd_buf, sizeof(password));
-			password[sizeof(password) - 1] = '\0';
-		}
-		pclose(fp);
-	}
-  }
-}
-
-static void sig_alarm(int sig)
-{
- if(!quiet_flag){
-   fprintf(stderr,"failed: %s: Timeout, nothing happened for %d seconds.\n", pname, time_out);
-   fprintf(stderr,"failed: %s: Perhaps you should inspect the RackSwitch at %s\n",pname,ipaddr);
- }
- exit(DID_FAILURE);	
-}
-
-
-int main(int argc, char **argv)
-{
-  int n,i,j,pnumb;
-  int ip_portnumber = 1025;
-  char boardnum = 0x00;
-  /*char number_of_action = 0x01;*/
-  int number_of_config_mobo = 0;
-  int number_of_section_config_mobo = 0;
-  int exit_status= 0;
-  int success_off = 0;
-  /*int success_on = 0;*/
-  int read_more = 1;
-  struct sockaddr_in rackaddr; 
-  
-  /*char mobo_enabled = 0x01;*/
-  /*char mobo_default_status = 0x00;*/
-  /*char mobo_output_status = 0x00;*/
-  int this_mobo = 0;
-  /*int mobo_id = 0;*/
-  /*int our_mobo = 0;*/
-  int number_of_temp = 0;
-
-  memset(arg, 0, 256);
-  memset(name, 0, 256);
-  memset(ipaddr, 0, 256);
-  memset(portnumber,0,256);
-  memset(username,0,256);
-  memset(password,0,256);
-
-  /*
-   * Ensure that we always get out of the fencing agent
-   * even if things get fucked up and we get no replies
-   */
-  signal(SIGALRM, &sig_alarm);
-  alarm(time_out);
-  get_options(argc, argv);
-
-  if(name[0] == '\0')
-  {
-    if(!quiet_flag)
-      fprintf(stderr,"failed: no name for this program\n");
-    exit(DID_FAILURE);
-  }
-  
-  if(ipaddr[0] == '\0')
-  {
-    if(!quiet_flag)
-      fprintf(stderr,"failed: %s, no IP address given\n",name);
-    exit(DID_FAILURE);
-  }
-  if (portnumber[0] == '\0')
-  {
-    if(!quiet_flag)
-      fprintf(stderr,"failed: %s, no portnumber given\n",name);
-    exit(DID_FAILURE);
-  }
-  if (username[0] == '\0')
-  {
-    if(!quiet_flag)
-      fprintf(stderr,"failed: %s, no username given\n",name);
-    exit(DID_FAILURE);
-  }
-
-  if (password[0] == '\0')
-  {
-    if(!quiet_flag)
-      fprintf(stderr,"failed: %s, no password given\n",name);
-    exit(DID_FAILURE);
-  }
-  /*
-   * Port number given to us as a string.
-   * Does the number make sense?
-   */
-  pnumb = 0;
-  for(n=0;(portnumber[n]!='\0');n++){
-    if((portnumber[n] < 48) || (portnumber[n] > 57)){
-      if(!quiet_flag)
-	fprintf(stderr,"failed: %s, invalid port number\n",name);
-      exit(1);
-    }
-    pnumb = ((pnumb * 10) + ((int)(portnumber[n]) - 48));
-  }
-  /*
-   * what section of the rack is this port part of?
-   * The switch has 4 "subsections", called boardnum here
-   */
-  if((pnumb > 0) && (pnumb < 47))
-    boardnum = 0x02;
-  if((pnumb > 46) && (pnumb < 94))
-    boardnum = 0x03;
-  if((pnumb > 93) && (pnumb < 137))
-    boardnum = 0x04;
-  if((pnumb < 1) || (pnumb> 136)){
-    boardnum = 0x00;
-    if(!quiet_flag)
-      fprintf(stderr,"failed: %s, the portnumber given is not in the range [1 - 136]\n",name);
-    exit(DID_FAILURE);
-  } 
-  /*********************************************
-   ***
-   *** set up TCP connection to the rackswitch
-   ***
-   ********************************************/
-  if ((sock = socket(AF_INET,SOCK_STREAM,0)) < 0){
-    fprintf(stderr,"failed: %s: socket error, %s\n",name,strerror(errno));
-    exit(DID_FAILURE);
-  }
-  
-  bzero(&rackaddr,sizeof(rackaddr));
-  rackaddr.sin_family = AF_INET;
-  rackaddr.sin_port = htons(ip_portnumber);
-
-  if(inet_pton(AF_INET,ipaddr,&rackaddr.sin_addr) <= 0){
-    fprintf(stderr,"failed: %s: inet_pton error\n", name);
-  }
- 
-  if(connect(sock,(SA *) &rackaddr,sizeof(rackaddr)) < 0){
-    fprintf(stderr,"failed: %s: connect error to %s, %s\n", name, ipaddr,strerror(errno));
-    exit(DID_FAILURE);
-  }
-  /**********************************************
-   ***
-   ***	Send Login Frame
-   ***
-   *********************************************/
-  writebuf[0] = op_login;
-   
-  for(n=0;n<=(strlen(username));n++){
-    writebuf[sizeof(char)+n] = username[n];
-  }
-  writebuf[sizeof(char)+(strlen(username))+1] ='\n';
-   
-  for(n=0;n<=(strlen(password))+1;n++){
-    writebuf[sizeof(char)+strlen(username)+1+n] = password[n];
-  }
-  writebuf[sizeof(char)+(strlen(username))+1+(strlen(password))+1] ='\n';
-     
-  if(write(sock,writebuf,sizeof(char)+strlen(username)+strlen(password)+2) < 0) {
-    fprintf(stderr,"failed to write to socket\n");
-    exit(DID_FAILURE);
-  }
-   
-  /********************************************
-   ***
-   ***	Read Login Reply
-   ***
-   *******************************************/
- if(wait_frame(ack_login)){
-   n=read(sock,readbuf,1);
-   if(readbuf[0] == login_deny){
-     if(!quiet_flag){fprintf(stderr,"failed: %s: Not able to log into RackSwitch\n",name);}
-     exit(DID_FAILURE);
-   }
-   else{
-     if(verbose_flag){printf("%s: Successfully logged into RackSwitch\n",name);}
-   }
-  }
-
- /********************************************
-  ***
-  ***	Send Configuration Request Message
-  ***
-  *******************************************/
- 
- writebuf[0] = configuration_request;
- writebuf[1] = config_general;
- if(write(sock,writebuf,2*(sizeof(char))) < 0) {
-   fprintf(stderr,"failed to write to socket\n");
-   exit(DID_FAILURE);
- }
-
- /********************************************
-   ***
-   ***	Read General Configuration Message
-   ***
-   *******************************************/
-
- if(wait_frame(config_reply)){
-   n = read(sock,readbuf,1);
-   if(readbuf[0] == config_general){
-
-     /* Configuration Status, one byte */
-     n = read(sock,readbuf,1);
-     
-     /* Switch description, string */
-     read_more = 1;
-     while(read_more){         
-       n = read(sock,readbuf,1);
-       if(readbuf[0] == '\0'){
-	 read_more = 0;
-       }
-       else{
-	 read_more = 1;
-       }
-     }
-     
-     /* Serial number, string */
-     read_more = 1;
-     while(read_more){
-       n = read(sock,readbuf,1);
-       if(readbuf[0] == '\0'){
-	 read_more = 0;
-       }
-       else{
-	 read_more = 1;
-       }
-     }
-
-       	  /* Version number, string */
-     read_more = 1;
-     while(read_more){
-       n = read(sock,readbuf,1);
-       if(readbuf[0] == '\0'){
-	 read_more = 0;
-       }
-       else{
-	 read_more = 1;
-       }
-     }
-
-     /* number of configured temps, 1 byte */
-     number_of_temp = 0; 
-     n = read(sock,readbuf,1);
-     number_of_temp = (int)readbuf[0];
-     
-     for(i=0;i<number_of_temp;i++){
-
-       /* Temprature description, string */
-       read_more = 1;
-       while(read_more){ 
-	 read_more = 1;
-	 while(read_more){         
-	   n = read(sock,readbuf,1);
-	   if(readbuf[0] == '\0'){
-	     read_more = 0;
-	   }
-	   else{
-	     read_more = 1;
-	   }
-	 }
-       }
-       
-       n = read(sock,readbuf,1); /* Temprature input ID */
-       n = read(sock,readbuf,1); /* Tempratue unit */
-       n = read(sock,readbuf,8); /* Temprature HI alarm */
-       n = read(sock,readbuf,8); /* Temprature LO alarm */
-       n = read(sock,readbuf,1); /* Temprature HI Alarm */
-       n = read(sock,readbuf,1); /* Temprature LO Alarm */
-       n = read(sock,readbuf,1); /* Temprature Alarm email */
-     }
-     /* Number of configured motherboards */
-     number_of_config_mobo = 0;
-     for(i=4;i>0;i--){
-       read_more = 1;	
-       while(read_more){
-	 n=read(sock,readbuf,1);
-	 if(n == 1){
-	   read_more = 0;
-	   number_of_config_mobo = number_of_config_mobo + (int)(readbuf[0]<<(8*(i-1)));
-	 }
-       }
-     }
-     /*
-      * make sure the motherboard we are asked to turn of is configured
-      */
-     if(pnumb > number_of_config_mobo){
-       if(!quiet_flag){
-	 fprintf(stderr,"failed: %s asked to reboot port %d, but there are only %d ports configured\n",name,pnumb,number_of_config_mobo);
-	 exit(DID_FAILURE);
-       }
-     }
-     n = read(sock,readbuf,1); /* email alarms */
-     n = read(sock,readbuf,4); /* email alarm delay */
-
-     /* email addresses, string */
-     read_more = 1;
-     while(read_more){         
-       n = read(sock,readbuf,1);
-       if(readbuf[0] == '\0'){
-	 read_more = 0;
-       }
-       else{
-	 read_more = 1;
-       }
-     }
-     
-     n = read(sock,readbuf,4); /* reset action duration */
-     n = read(sock,readbuf,4); /* power off action duration */
-     n = read(sock,readbuf,4); /* power on action duration */
-   }
-   else{
-     if(debug_flag){fprintf(stderr,"failed: %s: Did not receive general configuration frame when requested\n",name);}
-     exit(DID_FAILURE);
-   }
- }
- else{
-   if(debug_flag){fprintf(stderr,"failed: %s: Did not receive configuration frame when requested\n",name);}
-   exit(DID_FAILURE);
- }
-
-
-
- /******************************************
-  ***
-  ***	Send Action packet to switch
-  ***	Off/On port <portnum>
-  ***
-  *****************************************/
- memset(writebuf,0,sizeof(writebuf));
- writebuf[0] = op_action; 
- writebuf[1] = (char)(number_of_config_mobo >> 24);
- writebuf[2] = (char)(number_of_config_mobo >> 16);
- writebuf[3] = (char)(number_of_config_mobo >> 8);
- writebuf[4] = (char)(number_of_config_mobo);
- 
- writebuf[(pnumb*5)+0] = (char)(pnumb >> 24);
- writebuf[(pnumb*5)+1] = (char)(pnumb >> 16);
- writebuf[(pnumb*5)+2] = (char)(pnumb >> 8);
- writebuf[(pnumb*5)+3] = (char)(pnumb);
- writebuf[(pnumb*5)+4] = action_offon;
-
- if(write(sock,writebuf,(pnumb*5)+5) < 0) {
-   fprintf(stderr,"failed to write to socket\n");
-   exit(DID_FAILURE);
- }
- if(verbose_flag){
-   printf("%s: sending action frame to switch:\n",name);
-   for(i=0;i<(pnumb*5)+5;i++) 
-     printf("0x%.2x ",writebuf[i]);
-   printf("\n");
- }
-
-  /******************************************
-   ***
-   ***	Send Configuration Request packet to switch
-   ***
-   *****************************************/
- memset(writebuf,0,sizeof(writebuf));
- writebuf[0] = configuration_request;
- writebuf[1] = boardnum;
- 
- if(write(sock,writebuf,2*(sizeof(char))) < 0) {
-   fprintf(stderr,"failed to write to socket\n");
-   exit(DID_FAILURE);
- }
- if(verbose_flag){
-   printf("%s: sending Request Configuration Frame from switch:\n",name);
-   printf("0x%.2x 0x%.2x\n",writebuf[0],writebuf[1]);
- }
-
- /*******************************************
-  ***
-  ***	Read Switch Status Message
-  ***
-  ******************************************/
- while(success_off == 0){
-   if(debug_flag){
-     printf("%s: Status does not indicate port %d being rebooted. Looking again\n",name,pnumb);}
-   if(wait_frame(message_status)){
-     n = read(sock,readbuf,1); /* Rackswitch status */
-     
-     read_more = 1;
-     while(read_more){         /* Date & time */
-       n = read(sock,readbuf,1);
-       if(readbuf[0] == '\0'){
-	 read_more = 0;
-       }
-       else{
-	 read_more = 1;
-       }
-     }
-     number_of_temp = 0;
-     n = read(sock,readbuf,1);
-     number_of_temp = readbuf[0];
-     for(i=0;i<number_of_temp;i++){
-       read_more = 1;
-       while(read_more){
-	 n = read(sock,readbuf,1); /* Temprature input ID */
-	 n = read(sock,readbuf,8); /* Temprature Value, Fahrenheit */
-	 n = read(sock,readbuf,8); /* Temprature Vaule, Celcius */
-	 n = read(sock,readbuf,1); /* Temprature Alarm */
-       }
-     }
-     
-     /* number of motherboards, 4 byte */
-     number_of_section_config_mobo = 0;
-     for(i=4;i>0;i--){
-       read_more = 1;	
-       while(read_more){
-	 n=read(sock,readbuf,1);
-	 if(n == 1){
-	   read_more = 0;
-	   number_of_section_config_mobo = number_of_section_config_mobo + (int)(readbuf[0]<<(8*(i-1)));
-	 }
-       }
-     }
-     
-     for(i=0;i<number_of_section_config_mobo;i++){
-       
-       this_mobo = 0;
-       for(j=4;j>0;j--){
-	 read_more = 1;	
-	 while(read_more){
-	   n=read(sock,readbuf,1);
-	   if(n == 1){
-	     read_more = 0;
-	     this_mobo = this_mobo + (int)(readbuf[0]<<(8*(j-1)));
-	   }
-	 }
-       }
-       if(debug_flag){printf("%s: port %d is currently ",name,this_mobo);}
-       n = read(sock,readbuf,1); /* Motherboard status */
-       if(debug_flag){printf("0x%.2x\n",readbuf[0]);}
-       if((pnumb == this_mobo) && ((readbuf[0] == 0x02)||(readbuf[0] == 0x03))){
-	 success_off = 1;
-	 if(verbose_flag){printf("%s: Status shows port %d being rebooted\n",name,this_mobo);}
-       }
-     } /* end number_of_section_mobo loop */
-     if(!success_off){
-       if(verbose_flag){printf("%s: Status shows port %d NOT being rebooted, asking for status again\n",name,pnumb);}
-     }
-   }
-   else{
-     if(debug_flag){fprintf(stderr,"%s: Did not receive Switch Status Message\n",name);}
-     exit(DID_FAILURE);
-   }
- }
-
-
- if(success_off){
-	 if(!quiet_flag){	
-   printf("success: %s: successfully told RackSwitch to reboot port %d\n",name,pnumb);
-	 }   
-   alarm(0);
-   exit_status = DID_SUCCESS;
- }
- return(exit_status);
-}
-/* And that is it. There is no more.
- * Maybe there  should be more?
- * Or maybe not?
- * But there is no more
- */
diff --git a/fence/agents/rackswitch/do_rack.h b/fence/agents/rackswitch/do_rack.h
deleted file mode 100644
index 63c1365..0000000
--- a/fence/agents/rackswitch/do_rack.h
+++ /dev/null
@@ -1,27 +0,0 @@
-
-#include <unistd.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <limits.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <ctype.h>
-
-#include <sys/socket.h>
-#include <sys/types.h>
-
-#include <arpa/inet.h>
-
-#include <signal.h>
-
-#include "copyright.cf"
-
-#define SA struct sockaddr
-
-
-#define MAXBUF 1200
-
-#define DID_SUCCESS 0
-#define DID_FAILURE 1 
-
diff --git a/fence/agents/apc/Makefile.am b/fence/agents/raritan/Makefile.am
similarity index 63%
copy from fence/agents/apc/Makefile.am
copy to fence/agents/raritan/Makefile.am
index 355c873..bd751d0 100644
--- a/fence/agents/apc/Makefile.am
+++ b/fence/agents/raritan/Makefile.am
@@ -1,6 +1,6 @@
 MAINTAINERCLEANFILES	= Makefile.in
 
-TARGET			= fence_apc
+TARGET			= fence_raritan
 
 SRC			= $(TARGET).py
 
@@ -10,8 +10,8 @@ sbin_SCRIPTS		= $(TARGET)
 
 man_MANS		= $(TARGET).8
 
+FENCE_TEST_ARGS         = -l test -p test -a test -n 1
+
 include $(top_srcdir)/make/fencebuild.mk
 include $(top_srcdir)/make/fenceman.mk
-
-clean-local: clean-man
-	rm -f $(TARGET)
+include $(top_srcdir)/make/agentpycheck.mk
diff --git a/fence/agents/raritan/fence_raritan.py b/fence/agents/raritan/fence_raritan.py
new file mode 100644
index 0000000..502742e
--- /dev/null
+++ b/fence/agents/raritan/fence_raritan.py
@@ -0,0 +1,90 @@
+#!/usr/bin/python -tt
+
+import sys, re, pexpect
+import atexit
+sys.path.append("@FENCEAGENTSLIBDIR@")
+from fencing import *
+from fencing import fspawn, fail, EC_LOGIN_DENIED, run_delay
+
+#BEGIN_VERSION_GENERATION
+RELEASE_VERSION=""
+REDHAT_COPYRIGHT=""
+BUILD_DATE=""
+#END_VERSION_GENERATION
+
+# --plug should include path to the outlet # such as port 1:
+# /system1/outlet1
+
+def get_power_status(conn, options):
+	conn.send_eol("show -d properties=powerState %s" % options["--plug"])
+	re_status = re.compile(".*powerState is [12].*")
+	conn.log_expect(re_status, int(options["--shell-timeout"]))
+	status = {
+		#"0" : "off",
+		"1" : "on",
+		"2" : "off",
+	}[conn.after.split()[2]]
+
+	return status
+
+def set_power_status(conn, options):
+	action = {
+		"on" : "on",
+		"off" : "off",
+	}[options["--action"]]
+
+	conn.send_eol("set %s powerState=%s" % (options["--plug"], action))
+
+def main():
+	device_opt = ["ipaddr", "login", "passwd", "port", "telnet"]
+
+	atexit.register(atexit_handler)
+
+	opt = process_input(device_opt)
+
+	all_opt["ipport"]["default"] = "23"
+
+	opt["eol"] = "\r\n"
+	options = check_input(device_opt, opt)
+
+	docs = {}
+	docs["shortdesc"] = "I/O Fencing agent for Raritan Dominion PX"
+	docs["longdesc"] = "fence_raritan is an I/O Fencing agent which can be \
+used with the Raritan DPXS12-20 Power Distribution Unit. It logs into \
+device via telnet and reboots a specified outlet. Lengthy telnet connections \
+should be avoided while a GFS cluster is running because the connection will \
+block any necessary fencing actions."
+	docs["vendorurl"] = "http://www.raritan.com/"
+	show_docs(options, docs)
+
+	#  add support also for delay before login which is very useful for 2-node clusters
+	run_delay(options)
+
+	##
+	## Operate the fencing device
+	## We can not use fence_login(), username and passwd are sent on one line
+	####
+	try:
+		conn = fspawn(options, options["--telnet-path"])
+		conn.send("set binary\n")
+		conn.send("open %s -%s\n"%(options["--ip"], options["--ipport"]))
+		conn.read_nonblocking(size=100, timeout=int(options["--shell-timeout"]))
+		conn.log_expect("Login.*", int(options["--shell-timeout"]))
+		conn.send_eol("%s" % (options["--username"]))
+		conn.log_expect("Password.*", int(options["--shell-timeout"]))
+		conn.send_eol("%s" % (options["--password"]))
+		conn.log_expect("clp.*", int(options["--shell-timeout"]))
+	except pexpect.EOF:
+		fail(EC_LOGIN_DENIED)
+	except pexpect.TIMEOUT:
+		fail(EC_LOGIN_DENIED)
+
+	result = 0
+	if options["--action"] != "monitor":
+		result = fence_action(conn, options, set_power_status, get_power_status)
+
+	fence_logout(conn, "exit\n")
+	sys.exit(result)
+
+if __name__ == "__main__":
+	main()
diff --git a/fence/agents/rhevm/Makefile.am b/fence/agents/rhevm/Makefile.am
index 9552181..e50d747 100644
--- a/fence/agents/rhevm/Makefile.am
+++ b/fence/agents/rhevm/Makefile.am
@@ -10,8 +10,8 @@ sbin_SCRIPTS		= $(TARGET)
 
 man_MANS		= $(TARGET).8
 
+FENCE_TEST_ARGS         = -l test -p test -a test -n 1
+
 include $(top_srcdir)/make/fencebuild.mk
 include $(top_srcdir)/make/fenceman.mk
-
-clean-local: clean-man
-	rm -f $(TARGET)
+include $(top_srcdir)/make/agentpycheck.mk
diff --git a/fence/agents/rhevm/fence_rhevm.py b/fence/agents/rhevm/fence_rhevm.py
index d7fc326..427bed5 100644
--- a/fence/agents/rhevm/fence_rhevm.py
+++ b/fence/agents/rhevm/fence_rhevm.py
@@ -1,9 +1,12 @@
-#!/usr/bin/python
+#!/usr/bin/python -tt
 
 import sys, re
 import pycurl, StringIO
+import logging
+import atexit
 sys.path.append("@FENCEAGENTSLIBDIR@")
 from fencing import *
+from fencing import fail, EC_STATUS, run_delay
 
 #BEGIN_VERSION_GENERATION
 RELEASE_VERSION="New RHEV-M Agent - test release on steroids"
@@ -14,21 +17,23 @@ BUILD_DATE="March, 2008"
 
 RE_GET_ID = re.compile("<vm( .*)? id=\"(.*?)\"", re.IGNORECASE)
 RE_STATUS = re.compile("<state>(.*?)</state>", re.IGNORECASE)
-RE_GET_NAME = re.compile("<name>(.*?)</name>", re.IGNORECASE) 
+RE_GET_NAME = re.compile("<name>(.*?)</name>", re.IGNORECASE)
 
 def get_power_status(conn, options):
+	del conn
+
 	### Obtain real ID from name
 	res = send_command(options, "vms/?search=name%3D" + options["--plug"])
 
 	result = RE_GET_ID.search(res)
-	if (result == None):
+	if result == None:
 		# Unable to obtain ID needed to access virtual machine
 		fail(EC_STATUS)
 
 	options["id"] = result.group(2)
-	
+
 	result = RE_STATUS.search(res)
-	if (result == None):
+	if result == None:
 		# We were able to parse ID so output is correct
 		# in some cases it is possible that RHEV-M output does not
 		# contain <status> line. We can assume machine is OFF then
@@ -36,22 +41,24 @@ def get_power_status(conn, options):
 	else:
 		status = result.group(1)
 
-	if (status.lower() == "down"):
+	if status.lower() == "down":
 		return "off"
 	else:
 		return "on"
 
 def set_power_status(conn, options):
+	del conn
 	action = {
 		'on' : "start",
 		'off' : "stop"
 	}[options["--action"]]
 
 	url = "vms/" + options["id"] + "/" + action
-	res = send_command(options, url, "POST")
+	send_command(options, url, "POST")
 
 def get_list(conn, options):
-	outlets = { }
+	del conn
+	outlets = {}
 
 	try:
 		res = send_command(options, "vms")
@@ -61,15 +68,15 @@ def get_list(conn, options):
 			name = RE_GET_NAME.search(lines[i]).group(1)
 			outlets[name] = ("", None)
 	except AttributeError:
-		return { }
+		return {}
 	except IndexError:
-		return { }
+		return {}
 
 	return outlets
 
-def send_command(opt, command, method = "GET"):
+def send_command(opt, command, method="GET"):
 	## setup correct URL
-	if opt.has_key("--ssl"):
+	if opt.has_key("--ssl") or opt.has_key("--ssl-secure") or opt.has_key("--ssl-insecure"):
 		url = "https:"
 	else:
 		url = "http:"
@@ -77,39 +84,69 @@ def send_command(opt, command, method = "GET"):
 	url += "//" + opt["--ip"] + ":" + str(opt["--ipport"]) + "/api/" + command
 
 	## send command through pycurl
-	c = pycurl.Curl()
-	b = StringIO.StringIO()
-	c.setopt(pycurl.URL, url)
-	c.setopt(pycurl.HTTPHEADER, [ "Content-type: application/xml", "Accept: application/xml" ])
-	c.setopt(pycurl.HTTPAUTH, pycurl.HTTPAUTH_BASIC)
-	c.setopt(pycurl.USERPWD, opt["--username"] + ":" + opt["--password"])
-	c.setopt(pycurl.TIMEOUT, int(opt["--shell-timeout"]))
-	c.setopt(pycurl.SSL_VERIFYPEER, 0)
-	c.setopt(pycurl.SSL_VERIFYHOST, 0)
-
-	if (method == "POST"):
-		c.setopt(pycurl.POSTFIELDS, "<action />")
-
-	c.setopt(pycurl.WRITEFUNCTION, b.write)
-	c.perform()
-	result = b.getvalue()
-
-	if opt["log"] >= LOG_MODE_VERBOSE:
-		opt["debug_fh"].write(command + "\n")
-		opt["debug_fh"].write(result + "\n")
+	conn = pycurl.Curl()
+	web_buffer = StringIO.StringIO()
+	conn.setopt(pycurl.URL, url)
+	conn.setopt(pycurl.HTTPHEADER, ["Content-type: application/xml", "Accept: application/xml", "Prefer: persistent-auth"])
+
+	if opt.has_key("cookie"):
+		conn.setopt(pycurl.COOKIE, opt["cookie"])
+	else:
+		conn.setopt(pycurl.HTTPAUTH, pycurl.HTTPAUTH_BASIC)
+		conn.setopt(pycurl.USERPWD, opt["--username"] + ":" + opt["--password"])
+		if opt.has_key("--use-cookies"):
+			conn.setopt(pycurl.COOKIEFILE, "")
+
+	conn.setopt(pycurl.TIMEOUT, int(opt["--shell-timeout"]))
+	if opt.has_key("--ssl") or opt.has_key("--ssl-secure"):
+		conn.setopt(pycurl.SSL_VERIFYPEER, 1)
+		conn.setopt(pycurl.SSL_VERIFYHOST, 2)
+
+	if opt.has_key("--ssl-insecure"):
+		conn.setopt(pycurl.SSL_VERIFYPEER, 0)
+		conn.setopt(pycurl.SSL_VERIFYHOST, 0)
+
+	if method == "POST":
+		conn.setopt(pycurl.POSTFIELDS, "<action />")
+
+	conn.setopt(pycurl.WRITEFUNCTION, web_buffer.write)
+	conn.perform()
+
+	if not opt.has_key("cookie") and opt.has_key("--use-cookies"):
+		cookie = ""
+		for c in conn.getinfo(pycurl.INFO_COOKIELIST):
+			tokens = c.split("\t",7)
+			cookie = cookie + tokens[5] + "=" + tokens[6] + ";"
+
+		opt["cookie"] = cookie
+
+	result = web_buffer.getvalue()
+
+	logging.debug("%s\n", command)
+	logging.debug("%s\n", result)
 
 	return result
 
+def define_new_opts():
+	all_opt["use_cookies"] = {
+		"getopt" : "",
+		"longopt" : "use-cookies",
+		"help" : "--use-cookies                  Reuse cookies for authentication",
+		"required" : "0",
+		"shortdesc" : "Reuse cookies for authentication",
+		"order" : 1}
+
 def main():
-	device_opt = [ "ipaddr", "login", "passwd", "ssl", "web", "port" ]
+	device_opt = ["ipaddr", "login", "passwd", "ssl", "notls", "web", "port", "use_cookies" ]
 
 	atexit.register(atexit_handler)
+	define_new_opts()
 
 	all_opt["power_wait"]["default"] = "1"
-	
+
 	options = check_input(device_opt, process_input(device_opt))
 
-	docs = { }
+	docs = {}
 	docs["shortdesc"] = "Fence agent for RHEV-M REST API"
 	docs["longdesc"] = "fence_rhevm is an I/O Fencing agent which can be \
 used with RHEV-M REST API to fence virtual machines."
@@ -119,6 +156,7 @@ used with RHEV-M REST API to fence virtual machines."
 	##
 	## Fence operations
 	####
+	run_delay(options)
 	result = fence_action(None, options, set_power_status, get_power_status, get_list)
 
 	sys.exit(result)
diff --git a/fence/agents/rsa/Makefile.am b/fence/agents/rsa/Makefile.am
index 4bf1f1f..2536c7c 100644
--- a/fence/agents/rsa/Makefile.am
+++ b/fence/agents/rsa/Makefile.am
@@ -10,8 +10,8 @@ sbin_SCRIPTS		= $(TARGET)
 
 man_MANS		= $(TARGET).8
 
+FENCE_TEST_ARGS         = -l test -p test -a test
+
 include $(top_srcdir)/make/fencebuild.mk
 include $(top_srcdir)/make/fenceman.mk
-
-clean-local: clean-man
-	rm -f $(TARGET)
+include $(top_srcdir)/make/agentpycheck.mk
diff --git a/fence/agents/rsa/fence_rsa.py b/fence/agents/rsa/fence_rsa.py
index 117dd67..46f4bb9 100644
--- a/fence/agents/rsa/fence_rsa.py
+++ b/fence/agents/rsa/fence_rsa.py
@@ -1,4 +1,4 @@
-#!/usr/bin/python
+#!/usr/bin/python -tt
 
 #####
 ##
@@ -7,7 +7,8 @@
 ##
 #####
 
-import sys, re, pexpect, exceptions
+import sys, re
+import atexit
 sys.path.append("@FENCEAGENTSLIBDIR@")
 from fencing import *
 
@@ -19,10 +20,10 @@ BUILD_DATE=""
 
 def get_power_status(conn, options):
 	conn.send_eol("power state")
-	conn.log_expect(options, options["--command-prompt"], int(options["--shell-timeout"]))
-				
+	conn.log_expect(options["--command-prompt"], int(options["--shell-timeout"]))
+
 	match = re.compile("Power: (.*)", re.IGNORECASE).search(conn.before)
-	if (match != None):
+	if match != None:
 		status = match.group(1)
 	else:
 		status = "undefined"
@@ -31,21 +32,21 @@ def get_power_status(conn, options):
 
 def set_power_status(conn, options):
 	conn.send_eol("power " + options["--action"])
-	conn.log_expect(options, options["--command-prompt"], int(options["--power-timeout"]))
+	conn.log_expect(options["--command-prompt"], int(options["--power-timeout"]))
 
 def main():
-	device_opt = [ "ipaddr", "login", "passwd", "cmd_prompt", "secure" ]
+	device_opt = ["ipaddr", "login", "passwd", "cmd_prompt", "secure", "telnet"]
 
 	atexit.register(atexit_handler)
 
 	all_opt["login_timeout"]["default"] = 10
-	all_opt["cmd_prompt"]["default"] = [ ">" ]
+	all_opt["cmd_prompt"]["default"] = [">"]
 	# This device will not allow us to login even with LANG=C
 	all_opt["ssh_options"]["default"] = "-F /dev/null"
 
 	options = check_input(device_opt, process_input(device_opt))
 
-	docs = { }
+	docs = {}
 	docs["shortdesc"] = "Fence agent for IBM RSA"
 	docs["longdesc"] = "fence_rsa is an I/O Fencing agent \
 which can be used with the IBM RSA II management interface. It \
@@ -55,22 +56,13 @@ be avoided while a GFS cluster is running because the connection \
 will block any necessary fencing actions."
 	docs["vendorurl"] = "http://www.ibm.com"
 	show_docs(options, docs)
-	
+
 	##
 	## Operate the fencing device
 	######
 	conn = fence_login(options)
 	result = fence_action(conn, options, set_power_status, get_power_status, None)
-
-	##
-	## Logout from system
-	######
-	try:
-		conn.send_eol("exit")
-		conn.close()
-	except:
-		pass
-	
+	fence_logout(conn, "exit")
 	sys.exit(result)
 
 if __name__ == "__main__":
diff --git a/fence/agents/rsb/Makefile.am b/fence/agents/rsb/Makefile.am
index 939db98..5556020 100644
--- a/fence/agents/rsb/Makefile.am
+++ b/fence/agents/rsb/Makefile.am
@@ -10,8 +10,8 @@ sbin_SCRIPTS		= $(TARGET)
 
 man_MANS		= $(TARGET).8
 
+FENCE_TEST_ARGS         = -l test -p test -a test
+
 include $(top_srcdir)/make/fencebuild.mk
 include $(top_srcdir)/make/fenceman.mk
-
-clean-local: clean-man
-	rm -f $(TARGET)
+include $(top_srcdir)/make/agentpycheck.mk
diff --git a/fence/agents/rsb/fence_rsb.py b/fence/agents/rsb/fence_rsb.py
index da60a61..2ee85fe 100755
--- a/fence/agents/rsb/fence_rsb.py
+++ b/fence/agents/rsb/fence_rsb.py
@@ -1,6 +1,7 @@
-#!/usr/bin/python
+#!/usr/bin/python -tt
 
-import sys, re, pexpect, exceptions
+import sys, re
+import atexit
 sys.path.append("@FENCEAGENTSLIBDIR@")
 from fencing import *
 
@@ -12,12 +13,12 @@ BUILD_DATE=""
 
 def get_power_status(conn, options):
 	conn.send("2")
-	conn.log_expect(options, options["--command-prompt"], int(options["--shell-timeout"]))
-	status = re.compile("Power Status[\s]*: (on|off)", re.IGNORECASE).search(conn.before).group(1)
+	conn.log_expect(options["--command-prompt"], int(options["--shell-timeout"]))
+	status = re.compile(r"Power Status[\s]*: (on|off)", re.IGNORECASE).search(conn.before).group(1)
 	conn.send("0")
-	conn.log_expect(options, options["--command-prompt"], int(options["--shell-timeout"]))
+	conn.log_expect(options["--command-prompt"], int(options["--shell-timeout"]))
 
-	return (status.lower().strip())
+	return status.lower().strip()
 
 def set_power_status(conn, options):
 	action = {
@@ -26,32 +27,34 @@ def set_power_status(conn, options):
 	}[options["--action"]]
 
 	conn.send("2")
-	conn.log_expect(options, options["--command-prompt"], int(options["--shell-timeout"]))
+	conn.log_expect(options["--command-prompt"], int(options["--shell-timeout"]))
 	conn.send_eol(action)
-	conn.log_expect(options, ["want to power off", "'yes' or 'no'"], int(options["--shell-timeout"]))
+	conn.log_expect(["want to power " + options["--action"],
+			"yes/no", "'yes' or 'no'"], int(options["--shell-timeout"]))
 	conn.send_eol("yes")
-	conn.log_expect(options, "any key to continue", int(options["--power-timeout"]))
+	conn.log_expect("any key to continue", int(options["--power-timeout"]))
 	conn.send_eol("")
-	conn.log_expect(options, options["--command-prompt"], int(options["--shell-timeout"]))
+	conn.log_expect(options["--command-prompt"], int(options["--shell-timeout"]))
 	conn.send_eol("0")
-	conn.log_expect(options, options["--command-prompt"], int(options["--shell-timeout"]))
+	conn.log_expect(options["--command-prompt"], int(options["--shell-timeout"]))
 
 def main():
-	device_opt = [ "ipaddr", "login", "passwd", "secure", "cmd_prompt" ]
+	device_opt = ["ipaddr", "login", "passwd", "secure", "cmd_prompt", "telnet"]
 
 	atexit.register(atexit_handler)
 
-	all_opt["cmd_prompt"]["default"] = [ "to quit:" ]
+	all_opt["cmd_prompt"]["default"] = ["to quit:"]
 
 	opt = process_input(device_opt)
 
-	# set default port for telnet only
-	if 0 == opt.has_key("--ssh") and 0 == opt.has_key("--ipport"):
-		opt["--ipport"] = "3172"
+	if not opt.has_key("--ssh") and not opt.has_key("--ipport"):
+		# set default value like it should be set as usually
+		all_opt["ipport"]["default"] = "3172"
+		opt["--ipport"] = all_opt["ipport"]["default"]
 
 	options = check_input(device_opt, opt)
 
-	docs = { }
+	docs = {}
 	docs["shortdesc"] = "I/O Fencing agent for Fujitsu-Siemens RSB"
 	docs["longdesc"] = "fence_rsb is an I/O Fencing agent \
 which can be used with the Fujitsu-Siemens RSB management interface. It logs \
@@ -66,20 +69,7 @@ will block any necessary fencing actions."
 	####
 	conn = fence_login(options)
 	result = fence_action(conn, options, set_power_status, get_power_status, None)
-
-	##
-	## Logout from system
-	##
-	## In some special unspecified cases it is possible that 
-	## connection will be closed before we run close(). This is not 
-	## a problem because everything is checked before.
-	######
-	try:
-		conn.send_eol("0")
-		conn.close()
-	except:
-		pass
-	
+	fence_logout(conn, "0")
 	sys.exit(result)
 
 if __name__ == "__main__":
diff --git a/fence/agents/sanbox2/Makefile.am b/fence/agents/sanbox2/Makefile.am
index 9564bc8..f9c7c30 100644
--- a/fence/agents/sanbox2/Makefile.am
+++ b/fence/agents/sanbox2/Makefile.am
@@ -10,8 +10,8 @@ sbin_SCRIPTS		= $(TARGET)
 
 man_MANS		= $(TARGET).8
 
+FENCE_TEST_ARGS         = -l test -p test -a test -n 1
+
 include $(top_srcdir)/make/fencebuild.mk
 include $(top_srcdir)/make/fenceman.mk
-
-clean-local: clean-man
-	rm -f $(TARGET)
+include $(top_srcdir)/make/agentpycheck.mk
diff --git a/fence/agents/sanbox2/fence_sanbox2.py b/fence/agents/sanbox2/fence_sanbox2.py
index 5221d49..efa7dc8 100644
--- a/fence/agents/sanbox2/fence_sanbox2.py
+++ b/fence/agents/sanbox2/fence_sanbox2.py
@@ -1,4 +1,4 @@
-#!/usr/bin/python
+#!/usr/bin/python -tt
 
 #####
 ##
@@ -9,8 +9,11 @@
 #####
 
 import sys, re, pexpect, exceptions
+import logging
+import atexit
 sys.path.append("@FENCEAGENTSLIBDIR@")
 from fencing import *
+from fencing import fail, EC_TIMED_OUT, EC_GENERIC_ERROR
 
 #BEGIN_VERSION_GENERATION
 RELEASE_VERSION="New Sanbox2 Agent - test release on steroids"
@@ -25,17 +28,18 @@ def get_power_status(conn, options):
 	}
 	try:
 		conn.send_eol("show port " + options["--plug"])
-		conn.log_expect(options, options["--command-prompt"], int(options["--shell-timeout"]))
+		conn.log_expect(options["--command-prompt"], int(options["--shell-timeout"]))
 	except pexpect.TIMEOUT:
 		try:
 			conn.send_eol("admin end")
 			conn.send_eol("exit")
 			conn.close()
-		except:
+		except Exception:
 			pass
 		fail(EC_TIMED_OUT)
-	
-	status = re.compile(".*AdminState\s+(online|offline)\s+", re.IGNORECASE | re.MULTILINE).search(conn.before).group(1)
+
+	status = re.compile(r".*AdminState\s+(online|offline)\s+",
+			re.IGNORECASE | re.MULTILINE).search(conn.before).group(1)
 
 	try:
 		return status_trans[status.lower().strip()]
@@ -50,38 +54,38 @@ def set_power_status(conn, options):
 
 	try:
 		conn.send_eol("set port " + options["--plug"] + " state " + action)
-		conn.log_expect(options, options["--command-prompt"], int(options["--power-timeout"]))
+		conn.log_expect(options["--command-prompt"], int(options["--power-timeout"]))
 	except pexpect.TIMEOUT:
 		try:
 			conn.send_eol("admin end")
 			conn.send_eol("exit")
 			conn.close()
-		except:
+		except Exception:
 			pass
-		fail(EC_TIMED_OUT)                                                                         	
+		fail(EC_TIMED_OUT)
 
 	try:
 		conn.send_eol("set port " + options["--plug"] + " state " + action)
-		conn.log_expect(options, options["--command-prompt"], int(options["--power-timeout"]))
+		conn.log_expect(options["--command-prompt"], int(options["--power-timeout"]))
 	except pexpect.TIMEOUT:
 		try:
 			conn.send_eol("admin end")
 			conn.send_eol("exit")
 			conn.close()
-		except:
+		except Exception:
 			pass
 		fail(EC_TIMED_OUT)
 
 def get_list_devices(conn, options):
-	outlets = { }
+	outlets = {}
 
 	try:
 		conn.send_eol("show port")
-		conn.log_expect(options, options["--command-prompt"], int(options["--shell-timeout"]))
+		conn.log_expect(options["--command-prompt"], int(options["--shell-timeout"]))
 
-		list_re = re.compile("^\s+(\d+?)\s+(Online|Offline)\s+", re.IGNORECASE)
+		list_re = re.compile(r"^\s+(\d+?)\s+(Online|Offline)\s+", re.IGNORECASE)
 		for line in conn.before.splitlines():
-			if (list_re.search(line)):
+			if list_re.search(line):
 				status = {
 					'online' : "ON",
 					'offline' : "OFF"
@@ -93,22 +97,23 @@ def get_list_devices(conn, options):
 			conn.send_eol("admin end")
 			conn.send_eol("exit")
 			conn.close()
-		except:
+		except Exception:
 			pass
 		fail(EC_TIMED_OUT)
-		
+
 	return outlets
 
 def main():
-	device_opt = [ "fabric_fencing", "ipaddr", "login", "passwd", "cmd_prompt", "port" ]
+	device_opt = ["fabric_fencing", "ipaddr", "login", "passwd", "cmd_prompt", \
+		"port", "telnet"]
 
 	atexit.register(atexit_handler)
 
-	all_opt["cmd_prompt"]["default"] = [ " #> " ]
+	all_opt["cmd_prompt"]["default"] = [" #> "]
 
 	options = check_input(device_opt, process_input(device_opt))
 
-	docs = { }
+	docs = {}
 	docs["shortdesc"] = "Fence agent for QLogic SANBox2 FC switches"
 	docs["longdesc"] = "fence_sanbox2 is an I/O Fencing agent which can be used with \
 QLogic SANBox2 FC switches.  It logs into a SANBox2 switch via telnet and disables a specified \
@@ -124,12 +129,12 @@ because the connection will block any necessary fencing actions."
 	conn = fence_login(options)
 
 	conn.send_eol("admin start")
-	conn.log_expect(options, options["--command-prompt"], int(options["--shell-timeout"]))
+	conn.log_expect(options["--command-prompt"], int(options["--shell-timeout"]))
 
-	if (re.search("\(admin\)", conn.before, re.MULTILINE) == None):
+	if re.search(r"\(admin\)", conn.before, re.MULTILINE) == None:
 		## Someone else is in admin section, we can't enable/disable
 		## ports so we will rather exit
-		sys.stderr.write("Failed: Unable to switch to admin section\n")
+		logging.error("Failed: Unable to switch to admin section\n")
 		sys.exit(EC_GENERIC_ERROR)
 
 	result = fence_action(conn, options, set_power_status, get_power_status, get_list_devices)
diff --git a/fence/agents/scsi/Makefile.am b/fence/agents/scsi/Makefile.am
index 5652bda..295d649 100644
--- a/fence/agents/scsi/Makefile.am
+++ b/fence/agents/scsi/Makefile.am
@@ -2,20 +2,25 @@ MAINTAINERCLEANFILES	= Makefile.in
 
 TARGET			= fence_scsi
 
-SRC			= $(TARGET).pl
+SRC			= $(TARGET).py
 
-EXTRA_DIST		= $(SRC) \
-			  $(TARGET)_check.pl 
+EXTRA_DIST		= $(SRC) 
 
 scsidatadir		= $(CLUSTERDATA)
-
-scsidata_SCRIPTS	= $(TARGET)_check.pl
+scsidata_SCRIPTS	= fence_scsi_check
 
 sbin_SCRIPTS		= $(TARGET)
 
-dist_man_MANS		= $(TARGET).8
+man_MANS		= $(TARGET).8
+
+FENCE_TEST_ARGS         = -k 1
+
+fence_scsi_check: $(TARGET)
+	cp $^ $@
 
 include $(top_srcdir)/make/fencebuild.mk
+include $(top_srcdir)/make/fenceman.mk
+include $(top_srcdir)/make/agentpycheck.mk
 
-clean-local:
-	rm -f $(TARGET)
+clean-local: clean-man
+	rm -f $(TARGET) $(SYMTARGET) fence_scsi_check
diff --git a/fence/agents/scsi/fence_scsi.8 b/fence/agents/scsi/fence_scsi.8
deleted file mode 100644
index 180de4f..0000000
--- a/fence/agents/scsi/fence_scsi.8
+++ /dev/null
@@ -1,119 +0,0 @@
-.TH fence_scsi 8
-
-.SH NAME
-fence_scsi - I/O fencing agent for SCSI persistent reservations
-
-.SH SYNOPSIS
-.B
-fence_scsi
-[\fIOPTION\fR]...
-
-.SH DESCRIPTION
-fence_scsi is an I/O fencing agent that uses SCSI-3 persistent
-reservations to control access to shared storage devices. These
-devices must support SCSI-3 persistent reservations (SPC-3 or greater)
-as well as the "preempt-and-abort" subcommand.
-
-The fence_scsi agent works by having each node in the cluster register
-a unique key with the SCSI devive(s). Once registered, a single node
-will become the reservation holder by creating a "write exclusive,
-registrants only" reservation on the device(s). The result is that
-only registered nodes may write to the device(s). When a node failure
-occurs, the fence_scsi agent will remove the key belonging to the
-failed node from the device(s). The failed node will no longer be able
-to write to the device(s). A manual reboot is required. In the cluster
-environment unfence action should be configured also.
-
-Keys are either be specified manually (see -k option) or generated
-automatically (see -n option). Automatic key generation requires that
-cman be running. Keys will then be generated using the cluster ID and
-node ID such that each node has a unique key that can be determined by
-any other node in the cluster.
-
-Devices can either be specified manually (see -d option) or discovered
-automatically. Multiple devices can be specified manually by using a
-comma-separated list. If no devices are specified, the fence_scsi
-agent will attempt to discover devices by looking for cluster volumes
-and extracting the underlying devices. Devices may be device-mapper
-multipath devices or raw devices. If using a device-mapper multipath
-device, the fence_scsi agent will find the underlying devices (paths)
-and created registrations for each path.
-
-.SH OPTIONS
-.TP
-\fB-o\fP \fIaction\fR
-Fencing action. This value can be "on", "off", "status", or
-"metadata". The "on", "off", and "status" actions require either a key
-(see -k option) or node name (see -n option). For "on", the agent will
-attempt to register with the device(s) and create a reservation if
-none exists. The "off" action will attempt to remove a node's key from
-the device(s). The "status" action will report whether or not a node's
-key is currently register with one or more of the devices. The
-"metadata" action will display the XML metadata. The default action if
-"off".
-.TP
-\fB-d\fP \fIdevices\fR
-List of devices to use for current operation. Devices can be
-comma-separated list of raw device (eg. /dev/sdc) or device-mapper
-multipath devices (eg. /dev/dm-3). Each device must support SCSI-3
-persistent reservations.
-.TP
-\fB-f\fP \fIlogfile\fR
-Log output to file.
-.TP
-\fB-n\fP \fInodename\fR
-Name of the node to be fenced. The node name is used to generate the
-key value used for the current operation. This option will be ignored
-when used with the -k option.
-.TP
-\fB-k\fP \fIkey\fR
-Key to use for the current operation. This key should be unique to a
-node. For the "on" action, the key specifies the key use to register
-the local node. For the "off" action, this key specifies the key to be
-removed from the device(s).
-.TP
-\fB-H\fP \fIdelay\fR
-Wait X seconds before fencing is started (Default Value: 0)
-
-.TP
-\fB-a\fP
-Use the APTPL flag for registrations. This option is only used for the
-"on" action.
-.TP
-\fB-h\fP
-Print out a help message describing available options, then exit.
-.TP
-\fB-v\fP
-Verbose output.
-.TP
-\fB-V\fP
-Print out a version message, then exit.
-
-.SH STDIN PARAMETERS
-.TP
-\fIagent = "param"\fR
-This option is used by fence_node(8) and is ignored by fence_scsi.
-.TP
-\fInodename = "param"\fR
-Same as -n option.
-.TP
-\fIaction = "param" \fR
-Same as -o option.
-.TP
-\fIdevices = "param"\fR
-Same as -d option.
-.TP
-\fIlogfile = "param"\fR
-Same as -f option
-.TP
-\fIkey = "param"\fR
-Same as -k option.
-.TP
-\fIdelay = "param"\fR
-Same as -H option.
-.TP
-\fIaptpl = "1"
-Enable the APTPL flag. Default is 0 (disable).
-
-.SH SEE ALSO
-fence(8), fence_node(8), sg_persist(8), vgs(8), cman_tool(8), cman(5)
diff --git a/fence/agents/scsi/fence_scsi.pl b/fence/agents/scsi/fence_scsi.pl
deleted file mode 100644
index 6808ff5..0000000
--- a/fence/agents/scsi/fence_scsi.pl
+++ /dev/null
@@ -1,875 +0,0 @@
-#!/usr/bin/perl
-
-use Cwd 'realpath';
-use File::Basename;
-use File::Path;
-use Getopt::Std;
-use POSIX;
-use B;
-
-#BEGIN_VERSION_GENERATION
-$RELEASE_VERSION="";
-$REDHAT_COPYRIGHT="";
-$BUILD_DATE="";
-#END_VERSION_GENERATION
-
-my $ME = fileparse ($0, ".pl");
-
-################################################################################
-
-sub log_debug ($)
-{
-    my $time = strftime "%b %e %T", localtime;
-    my ($msg) = @_;
-
-    print STDOUT "$time $ME: [debug] $msg\n" unless defined ($opt_q);
-
-    return;
-}
-
-sub log_error ($)
-{
-    my $time = strftime "%b %e %T", localtime;
-    my ($msg) = @_;
-
-    print STDERR "$time $ME: [error] $msg\n" unless defined ($opt_q);
-
-    exit (1);
-}
-
-sub do_action_on ($@)
-{
-    my $self = (caller(0))[3];
-    my ($node_key, @devices) = @_;
-
-    key_write ($node_key);
-
-    foreach $dev (@devices) {
-	log_error ("device $dev does not exist") if (! -e $dev);
-	log_error ("device $dev is not a block device") if (! -b $dev);
-
-	if (do_register_ignore ($node_key, $dev) != 0) {
-	    log_error ("failed to create registration (key=$node_key, device=$dev)");
-	}
-
-	if (!get_reservation_key ($dev)) {
-	    if (do_reserve ($node_key, $dev) != 0) {
-		if (!get_reservation_key ($dev)) {
-		    log_error ("failed to create reservation (key=$node_key, device=$dev)");
-		}
-	    }
-	}
-    }
-
-    return;
-}
-
-sub do_action_off ($@)
-{
-    my $self = (caller(0))[3];
-    my ($node_key, @devices) = @_;
-
-    my $host_key = key_read ();
-
-    if ($host_key eq $node_key) {
-	log_error ($self);
-    }
-
-    foreach $dev (@devices) {
-	log_error ("device $dev does not exist") if (! -e $dev);
-	log_error ("device $dev is not a block device") if (! -b $dev);
-
-	my @keys = grep { /^$node_key$/i } get_registration_keys ($dev);
-
-	if (scalar (@keys) != 0) {
-	    do_preempt_abort ($host_key, $node_key, $dev);
-	}
-    }
-
-    return;
-}
-
-sub do_action_status ($@)
-{
-    my $self = (caller(0))[3];
-    my ($node_key, @devices) = @_;
-
-    my $dev_count = 0;
-    my $key_count = 0;
-
-    foreach $dev (@devices) {
-	log_error ("device $dev does not exist") if (! -e $dev);
-	log_error ("device $dev is not a block device") if (! -b $dev);
-
-	do_reset ($dev);
-
-	my @keys = grep { /^$node_key$/i } get_registration_keys ($dev);
-
-	if (scalar (@keys) != 0) {
-	    $dev_count++;
-	}
-    }
-
-    if ($dev_count != 0) {
-	exit (0);
-    } else {
-	exit (2);
-    }
-}
-
-sub do_verify_on ($@)
-{
-    my $self = (caller(0))[3];
-    my ($node_key, @devices) = @_;
-    my $count = 0;
-
-    for $dev (@devices) {
-        my @keys = grep { /^$node_key$/i } get_registration_keys ($dev);
-
-        ## check that our key is registered
-        if (scalar (@keys) == 0) {
-            log_debug ("failed to register key $node_key on device $dev");
-            $count++;
-            next;
-        }
-
-	## write dev to device file once registration is verified
-	dev_write ($dev);
-
-        ## check that a reservation exists
-        if (!get_reservation_key ($dev)) {
-            log_debug ("no reservation exists on device $dev");
-            $count++;
-        }
-    }
-
-    if ($count != 0) {
-        log_error ("$self: failed to verify $count devices");
-    }
-}
-
-sub do_verify_off ($@)
-{
-    my $self = (caller(0))[3];
-    my ($node_key, @devices) = @_;
-    my $count = 0;
-
-    for $dev (@devices) {
-        my @keys = grep { /^$node_key$/i } get_registration_keys ($dev);
-
-        ## check that our key is not registered
-        if (scalar (@keys) != 0) {
-            log_debug ("failed to remove key $node_key from device $dev");
-            $count++;
-            next;
-        }
-
-        ## check that a reservation exists
-        if (!get_reservation_key ($dev)) {
-            log_debug ("no reservation exists on device $dev");
-            $count++;
-        }
-    }
-
-    if ($count != 0) {
-        log_error ("$self: failed to verify $count devices");
-    }
-}
-
-sub do_register ($$$)
-{
-    my $self = (caller(0))[3];
-    my ($host_key, $node_key, $dev) = @_;
-
-    $dev = realpath ($dev);
-
-    if (substr ($dev, 5) =~ /^dm/) {
-	my @slaves = get_mpath_slaves ($dev);
-	foreach (@slaves) {
-	    do_register ($node_key, $_);
-	}
-	return;
-    }
-
-    log_debug ("$self (host_key=$host_key, node_key=$node_key, dev=$dev)");
-
-    my $cmd;
-    my $out;
-    my $err;
-
-    do_reset ($dev);
-
-    $cmd = "sg_persist -n -o -G -K $host_key -S $node_key -d $dev";
-    $cmd .= " -Z" if (defined $opt_a);
-    $out = qx { $cmd 2> /dev/null };
-    $err = ($?>>8);
-
-    # if ($err != 0) {
-    # 	log_error ("$self (err=$err)");
-    # }
-
-    log_debug ("$self (err=$err)");
-
-    return ($err);
-}
-
-sub do_register_ignore ($$)
-{
-    my $self = (caller(0))[3];
-    my ($node_key, $dev) = @_;
-
-    $dev = realpath ($dev);
-
-    if (substr ($dev, 5) =~ /^dm/) {
-	my @slaves = get_mpath_slaves ($dev);
-	foreach (@slaves) {
-	    do_register_ignore ($node_key, $_);
-	}
-	return;
-    }
-
-    log_debug ("$self (node_key=$node_key, dev=$dev)");
-
-    my $cmd;
-    my $out;
-    my $err;
-
-    do_reset ($dev);
-
-    $cmd = "sg_persist -n -o -I -S $node_key -d $dev";
-    $cmd .= " -Z" if (defined $opt_a);
-    $out = qx { $cmd 2> /dev/null };
-    $err = ($?>>8);
-
-    # if ($err != 0) {
-    # 	log_error ("$self (err=$err)");
-    # }
-
-    log_debug ("$self (err=$err)");
-
-    return ($err);
-}
-
-sub do_reserve ($$)
-{
-    my $self = (caller(0))[3];
-    my ($host_key, $dev) = @_;
-
-    log_debug ("$self (host_key=$host_key, dev=$dev)");
-
-    my $cmd = "sg_persist -n -o -R -T 5 -K $host_key -d $dev";
-    my $out = qx { $cmd 2> /dev/null };
-    my $err = ($?>>8);
-
-    # if ($err != 0) {
-    # 	log_error ("$self (err=$err)");
-    # }
-
-    log_debug ("$self (err=$err)");
-
-    return ($err);
-}
-
-sub do_release ($$)
-{
-    my $self = (caller(0))[3];
-    my ($host_key, $dev) = @_;
-
-    log_debug ("$self (host_key=$host_key, dev=$dev)");
-
-    my $cmd = "sg_persist -n -o -L -T 5 -K $host_key -d $dev";
-    my $out = qx { $cmd 2> /dev/null };
-    my $err = ($?>>8);
-
-    # if ($err != 0) {
-    # 	log_error ("$self (err=$err)");
-    # }
-
-    log_debug ("$self (err=$err)");
-
-    return ($err);
-}
-
-sub do_preempt ($$$)
-{
-    my $self = (caller(0))[3];
-    my ($host_key, $node_key, $dev) = @_;
-
-    log_debug ("$self (host_key=$host_key, node_key=$node_key, dev=$dev)");
-
-    my $cmd = "sg_persist -n -o -P -T 5 -K $host_key -S $node_key -d $dev";
-    my $out = qx { $cmd 2> /dev/null };
-    my $err = ($?>>8);
-
-    # if ($err != 0) {
-    # 	log_error ("$self (err=$err)");
-    # }
-
-    log_debug ("$self (err=$err)");
-
-    return ($err);
-}
-
-sub do_preempt_abort ($$$)
-{
-    my $self = (caller(0))[3];
-    my ($host_key, $node_key, $dev) = @_;
-
-    log_debug ("$self (host_key=$host_key, node_key=$node_key, dev=$dev)");
-
-    my $cmd = "sg_persist -n -o -A -T 5 -K $host_key -S $node_key -d $dev";
-    my $out = qx { $cmd 2> /dev/null };
-    my $err = ($?>>8);
-
-    # if ($err != 0) {
-    # 	log_error ("$self (err=$err)");
-    # }
-
-    log_debug ("$self (err=$err)");
-
-    return ($err);
-}
-
-sub do_reset (S)
-{
-    my $self = (caller(0))[3];
-    my ($dev) = @_;
-
-    my $cmd = "sg_turs $dev";
-    my @out = qx { $cmd 2> /dev/null };
-    my $err = ($?>>8);
-
-    ## note that it is not necessarily an error is $err is non-zero,
-    ## so just log the device and status and continue.
-
-    log_debug ("$self (dev=$dev, status=$err)");
-
-    return ($err);
-}
-
-sub dev_unlink ()
-{
-    my $self = (caller(0))[3];
-    my $file = "/var/run/cluster/fence_scsi.dev";
-
-    if (-e $file) {
-	unlink ($file) or die "$!\n";
-    }
-
-    return;
-}
-
-sub dev_write ($)
-{
-    my $self = (caller(0))[3];
-    my $file = "/var/run/cluster/fence_scsi.dev";
-    my $dev = shift;
-
-    if (! -d "/var/run/cluster") {
-	mkpath ("/var/run/cluster");
-    }
-
-    open (\*FILE, "+>>$file") or die "$!\n";
-
-    ## since the file is opened for read, write and append,
-    ## we need to seek to the beginning of the file before grep.
-
-    seek (FILE, 0, 0);
-
-    if (! grep { /^$dev$/ } <FILE>) {
-	print FILE "$dev\n";
-    }
-
-    close (FILE);
-
-    return;
-}
-
-sub key_read ()
-{
-    my $self = (caller(0))[3];
-    my $file = "/var/run/cluster/fence_scsi.key";
-    my $key;
-
-    open (\*FILE, "<$file") or die "$!\n";
-    chomp ($key = <FILE>);
-    close (FILE);
-
-    return ($key);
-}
-
-sub key_write ($)
-{
-    my $self = (caller(0))[3];
-    my $file = "/var/run/cluster/fence_scsi.key";
-    my $key = shift;
-
-    if (! -d "/var/run/cluster") {
-	mkpath ("/var/run/cluster");
-    }
-
-    open (\*FILE, ">$file") or die "$!\n";
-    print FILE "$key\n";
-    close (FILE);
-
-    return;
-}
-
-sub get_key ($)
-{
-    my $self = (caller(0))[3];
-
-    my $key = sprintf ("%.4x%.4x", get_cluster_id (), get_node_id ($_[0]));
-
-    return ($key);
-}
-
-sub get_node_id ($)
-{
-    my $self = (caller(0))[3];
-    my $node = $_[0];
-
-    my $cmd = "/usr/sbin/corosync-cmapctl nodelist.";
-    my @out = qx { $cmd 2> /dev/null };
-    my $err = ($?>>8);
-
-    if ($err != 0) {
-	log_error ("$self (err=$err)");
-    }
-
-    # die "[error]: $self\n" if ($?>>8);
-
-    foreach my $line (@out) {
-        chomp($line);
-        if ($line =~ /.(\d+?).ring._addr \(str\) = ${node}$/) {
-            return $1;
-        }
-    }
-                                        
-    log_error("$self (unable to parse output of corosync-cmapctl or node does not exist)");
-}
-
-sub get_cluster_id ()
-{
-    my $self = (caller(0))[3];
-    my $cluster_id;
-
-    my $cmd = "/usr/sbin/corosync-cmapctl totem.cluster_name";
-    my $out = qx { $cmd 2> /dev/null };
-    my $err = ($?>>8);
-
-    if ($err != 0) {
-	log_error ("$self (err=$err)");
-    }
-
-    # die "[error]: $self\n" if ($?>>8);
-
-    chomp($out);
-
-    if ($out =~ /=\s(.*?)$/) {
-        my $cluster_name = $1;
-        # tranform string to a number
-        $cluster_id = (hex B::hash($cluster_name)) % 65536;
-    } else {
-        log_error("$self (unable to parse output of corosync-cmapctl)");
-    }
-
-    return ($cluster_id);
-}
-
-sub get_devices_clvm ()
-{
-    my $self = (caller(0))[3];
-    my @devices;
-
-    my $cmd = "vgs --noheadings " .
-	"    --separator : " .
-	"    --sort pv_uuid " .
-	"    --options vg_attr,pv_name " .
-	"    --config 'global { locking_type = 0 } " .
-	"              devices { preferred_names = [ \"^/dev/dm\" ] }'";
-
-    my @out = qx { $cmd 2> /dev/null };
-    my $err = ($?>>8);
-
-    if ($err != 0) {
-	log_error ("$self (err=$err)");
-    }
-
-    # die "[error]: $self\n" if ($?>>8);
-
-    foreach (@out) {
-	chomp;
-	my ($vg_attr, $pv_name) = split (/:/, $_);
-	if ($vg_attr =~ /c$/) {
-	    push (@devices, $pv_name);
-	}
-    }
-
-    return (@devices);
-}
-
-sub get_devices_scsi ()
-{
-    my $self = (caller(0))[3];
-    my @devices;
-
-    opendir (\*DIR, "/sys/block/") or die "$!\n";
-    @devices = grep { /^sd/ } readdir (DIR);
-    closedir (DIR);
-
-    return (@devices);
-}
-
-sub get_mpath_name ($)
-{
-    my $self = (caller(0))[3];
-    my ($dev) = @_;
-    my $name;
-
-    if ($dev =~ /^\/dev\//) {
-	$dev = substr ($dev, 5);
-    }
-
-    open (\*FILE, "/sys/block/$dev/dm/name") or die "$!\n";
-    chomp ($name = <FILE>);
-    close (FILE);
-
-    return ($name);
-}
-
-sub get_mpath_uuid ($)
-{
-    my $self = (caller(0))[3];
-    my ($dev) = @_;
-    my $uuid;
-
-    if ($dev =~ /^\/dev\//) {
-	$dev = substr ($dev, 5);
-    }
-
-    open (\*FILE, "/sys/block/$dev/dm/uuid") or die "$!\n";
-    chomp ($uuid = <FILE>);
-    close (FILE);
-
-    return ($name);
-}
-
-sub get_mpath_slaves ($)
-{
-    my $self = (caller(0))[3];
-    my ($dev) = @_;
-    my @slaves;
-
-    if ($dev =~ /^\/dev\//) {
-	$dev = substr ($dev, 5);
-    }
-
-    opendir (\*DIR, "/sys/block/$dev/slaves/") or die "$!\n";
-
-    @slaves = grep { !/^\./ } readdir (DIR);
-    if ($slaves[0] =~ /^dm/) {
-	@slaves = get_mpath_slaves ($slaves[0]);
-    } else {
-	@slaves = map { "/dev/$_" } @slaves;
-    }
-
-    closedir (DIR);
-
-    return (@slaves);
-}
-
-sub get_registration_keys ($)
-{
-    my $self = (caller(0))[3];
-    my ($dev) = @_;
-    my @keys;
-
-    my $cmd = "sg_persist -n -i -k -d $dev";
-    my @out = qx { $cmd 2> /dev/null };
-    my $err = ($?>>8);
-
-    if ($err != 0) {
-	log_error ("$self (err=$err)");
-    }
-
-    # die "[error]: $self\n" if ($?>>8);
-
-    foreach (@out) {
-	chomp;
-	if ($_ =~ s/^\s+0x//i) {
-	    push (@keys, $_);
-	}
-    }
-
-    return (@keys);
-}
-
-sub get_reservation_key ($)
-{
-    my $self = (caller(0))[3];
-    my ($dev) = @_;
-    my $key;
-
-    my $cmd = "sg_persist -n -i -r -d $dev";
-    my @out = qx { $cmd 2> /dev/null };
-    my $err = ($?>>8);
-
-    if ($err != 0) {
-	log_error ("$self (err=$err)");
-    }
-
-    # die "[error]: $self\n" if ($?>>8);
-
-    foreach (@out) {
-	chomp;
-	if ($_ =~ s/^\s+key=0x//i) {
-	    $key = $_;
-	    last;
-	}
-    }
-
-    return ($key)
-}
-
-sub get_options_stdin ()
-{
-    my $num = 0;
-
-    while (<STDIN>) {
-	chomp;
-	s/^\s*//;
-	s/\s*$//;
-
-	next if (/^#/);
-
-	$num++;
-
-	next unless ($_);
-
-	my ($opt, $arg) = split (/\s*=\s*/, $_);
-
-	if ($opt eq "") {
-	    exit (1);
-	}
-	elsif ($opt eq "aptpl") {
-	    $opt_a = $arg;
-	}
-	elsif ($opt eq "devices") {
-	    $opt_d = $arg;
-	}
-	elsif ($opt eq "logfile") {
-	    $opt_f = $arg;
-	}
-	elsif ($opt eq "key") {
-	    $opt_k = $arg;
-	}
-	elsif ($opt eq "nodename") {
-	    $opt_n = $arg;
-	}
-	elsif ($opt eq "action") {
-	    $opt_o = $arg;
-	}
-	elsif ($opt eq "delay") {
-	    $opt_H = $arg;
-	}
-    }
-}
-
-sub print_usage ()
-{
-    print "Usage:\n";
-    print "\n";
-    print "$ME [options]\n";
-    print "\n";
-    print "Options:\n";
-    print "  -a               Use APTPL flag\n";
-    print "  -d <devices>     Devices to be used for action\n";
-    print "  -f <logfile>     File to write debug/error output\n";
-    print "  -H <timeout>     Wait X seconds before fencing is started\n";
-    print "  -h               Usage\n";
-    print "  -k <key>         Key to be used for current action\n";
-    print "  -n <nodename>    Name of node to operate on\n";
-    print "  -o <action>      Action: off (default), on, or status\n";
-    print "  -q               Quiet mode\n";
-    print "  -V               Version\n";
-
-    exit (0);
-}
-
-sub print_version ()
-{
-    print "$ME $RELEASE_VERSION $BUILD_DATE\n";
-    print "$REDHAT_COPYRIGHT\n" if ( $REDHAT_COPYRIGHT );
-
-    exit (0);
-}
-
-sub print_metadata ()
-{
-    print "<?xml version=\"1.0\" ?>\n";
-    print "<resource-agent name=\"fence_scsi\"" .
-          " shortdesc=\"fence agent for SCSI-3 persistent reservations\">\n";
-    print "<longdesc>fence_scsi</longdesc>\n";
-    print "<vendor-url>http://www.t10.org</vendor-url>\n";
-    print "<parameters>\n";
-    print "\t<parameter name=\"aptpl\" unique=\"0\" required=\"0\">\n";
-    print "\t\t<getopt mixed=\"-a\"/>\n";
-    print "\t\t<content type=\"boolean\"/>\n";
-    print "\t\t<shortdesc lang=\"en\">" .
-          "Use APTPL flag for registrations" .
-          "</shortdesc>\n";
-    print "\t</parameter>\n";
-    print "\t<parameter name=\"devices\" unique=\"0\" required=\"0\">\n";
-    print "\t\t<getopt mixed=\"-d\"/>\n";
-    print "\t\t<content type=\"string\"/>\n";
-    print "\t\t<shortdesc lang=\"en\">" .
-          "List of devices to be used for fencing action" .
-          "</shortdesc>\n";
-    print "\t</parameter>\n";
-    print "\t<parameter name=\"logfile\" unique=\"0\" required=\"0\">\n";
-    print "\t\t<getopt mixed=\"-f\"/>\n";
-    print "\t\t<content type=\"string\"/>\n";
-    print "\t\t<shortdesc lang=\"en\">" .
-          "File to write error/debug messages" .
-          "</shortdesc>\n";
-    print "\t</parameter>\n";
-    print "\t<parameter name=\"delay\" unique=\"0\" required=\"0\">\n";
-    print "\t\t<getopt mixed=\"-H\"/>\n";
-    print "\t\t<content type=\"string\"/>\n";
-    print "\t\t<shortdesc lang=\"en\">" .
-          "Wait X seconds before fencing is started" .
-          "</shortdesc>\n";
-    print "\t</parameter>\n";
-    print "\t<parameter name=\"key\" unique=\"0\" required=\"0\">\n";
-    print "\t\t<getopt mixed=\"-k\"/>\n";
-    print "\t\t<content type=\"string\"/>\n";
-    print "\t\t<shortdesc lang=\"en\">" .
-          "Key value to be used for fencing action" .
-          "</shortdesc>\n";
-    print "\t</parameter>\n";
-    print "\t<parameter name=\"action\" unique=\"0\" required=\"0\">\n";
-    print "\t\t<getopt mixed=\"-o\"/>\n";
-    print "\t\t<content type=\"string\" default=\"off\"/>\n";
-    print "\t\t<shortdesc lang=\"en\">" .
-          "Fencing action" .
-          "</shortdesc>\n";
-    print "\t</parameter>\n";
-    print "\t<parameter name=\"nodename\" unique=\"0\" required=\"0\">\n";
-    print "\t\t<getopt mixed=\"-n\"/>\n";
-    print "\t\t<content type=\"string\"/>\n";
-    print "\t\t<shortdesc lang=\"en\">" .
-          "Name of node" .
-          "</shortdesc>\n";
-    print "\t</parameter>\n";
-    print "</parameters>\n";
-    print "<actions>\n";
-    print "\t<action name=\"on\" on_target=\"1\" automatic=\"1\"/>\n";
-    print "\t<action name=\"off\"/>\n";
-    print "\t<action name=\"status\"/>\n";
-    print "\t<action name=\"metadata\"/>\n";
-    print "</actions>\n";
-    print "</resource-agent>\n";
-
-    exit (0);
-}
-
-################################################################################
-
-if (@ARGV > 0) {
-    getopts ("ad:f:H:hk:n:o:qV") or print_usage;
-    print_usage if (defined $opt_h);
-    print_version if (defined $opt_V);
-} else {
-    get_options_stdin ();
-}
-
-## handle the metadata action here to avoid other parameter checks
-##
-if ($opt_o =~ /^metadata$/i) {
-    print_metadata;
-}
-
-## if the logfile (-f) parameter was specified, open the logfile
-## and redirect STDOUT and STDERR to the logfile.
-##
-if (defined $opt_f) {
-    open (LOG, ">>$opt_f") or die "$!\n";
-    open (STDOUT, ">&LOG");
-    open (STDERR, ">&LOG");
-}
-
-## verify that either key or nodename have been specified
-##
-if ((!defined $opt_n) && (!defined $opt_k)) {
-    print_usage ();
-}
-
-## determine key value
-##
-if (defined $opt_k) {
-    $key = $opt_k;
-} else {
-    $key = get_key ($opt_n);
-}
-
-## verify that key is not zero
-##
-if (hex($key) == 0) {
-    log_error ("key cannot be zero");
-}
-
-## remove any leading zeros from key
-##
-if ($key =~ /^0/) {
-    $key =~ s/^0+//;
-}
-
-## get devices
-##
-if (defined $opt_d) {
-    @devices = split (/\s*,\s*/, $opt_d);
-} else {
-    @devices = get_devices_clvm ();
-}
-
-## verify that device list is not empty
-##
-if (scalar (@devices) == 0) {
-    log_error ("no devices found");
-}
-
-## default action is "off"
-##
-if (!defined $opt_o) {
-    $opt_o = "off";
-}
-
-## Wait for defined period (-H / delay= )
-##
-if ((defined $opt_H) && ($opt_H =~ /^[0-9]+/)) {
-    sleep($opt_H);
-}
-
-## determine the action to perform
-##
-if ($opt_o =~ /^on$/i) {
-    do_action_on ($key, @devices);
-    do_verify_on ($key, @devices);
-}
-elsif ($opt_o =~ /^off$/i) {
-    do_action_off ($key, @devices);
-    do_verify_off ($key, @devices);
-}
-elsif ($opt_o =~ /^status/i) {
-    do_action_status ($key, @devices);
-} else {
-    log_error ("unknown action '$opt_o'");
-    exit (1);
-}
-
-## close the logfile
-##
-if (defined $opt_f) {
-    close (LOG);
-}
diff --git a/fence/agents/scsi/fence_scsi.py b/fence/agents/scsi/fence_scsi.py
new file mode 100644
index 0000000..a466f20
--- /dev/null
+++ b/fence/agents/scsi/fence_scsi.py
@@ -0,0 +1,454 @@
+#!/usr/bin/python -tt
+
+import sys
+import stat
+import re
+import os
+import time
+import logging
+import atexit
+import hashlib
+sys.path.append("@FENCEAGENTSLIBDIR@")
+from fencing import fail_usage, run_command, atexit_handler, check_input, process_input, show_docs, fence_action, all_opt
+from fencing import run_delay
+
+#BEGIN_VERSION_GENERATION
+RELEASE_VERSION=""
+REDHAT_COPYRIGHT=""
+BUILD_DATE=""
+#END_VERSION_GENERATION
+
+STORE_PATH = "/var/run/cluster/fence_scsi"
+
+
+def get_status(conn, options):
+	del conn
+	status = "off"
+	for dev in options["devices"]:
+		is_block_device(dev)
+		reset_dev(options, dev)
+		if options["--key"] in get_registration_keys(options, dev):
+			status = "on"
+		else:
+			logging.debug("No registration for key "\
+				+ options["--key"] + " on device " + dev + "\n")
+	return status
+
+
+def set_status(conn, options):
+	del conn
+	count = 0
+	if options["--action"] == "on":
+		set_key(options)
+		for dev in options["devices"]:
+			is_block_device(dev)
+
+			register_dev(options, dev)
+			if options["--key"] not in get_registration_keys(options, dev):
+				count += 1
+				logging.debug("Failed to register key "\
+					+ options["--key"] + "on device " + dev + "\n")
+				continue
+			dev_write(dev, options)
+
+			if get_reservation_key(options, dev) is None \
+			and not reserve_dev(options, dev) \
+			and get_reservation_key(options, dev) is None:
+				count += 1
+				logging.debug("Failed to create reservation (key="\
+					+ options["--key"] + ", device=" + dev + ")\n")
+
+	else:
+		host_key = get_key()
+		if host_key == options["--key"].lower():
+			fail_usage("Failed: keys cannot be same. You can not fence yourself.")
+		for dev in options["devices"]:
+			is_block_device(dev)
+
+			if options["--key"] in get_registration_keys(options, dev):
+				preempt_abort(options, host_key, dev)
+
+		for dev in options["devices"]:
+			if options["--key"] in get_registration_keys(options, dev):
+				count += 1
+				logging.debug("Failed to remove key "\
+					+ options["--key"] + " on device " + dev + "\n")
+				continue
+
+			if not get_reservation_key(options, dev):
+				count += 1
+				logging.debug("No reservation exists on device " + dev + "\n")
+	if count:
+		logging.error("Failed to verify " + str(count) + " device(s)")
+		sys.exit(1)
+
+
+#run command, returns dict, ret["err"] = exit code; ret["out"] = output
+def run_cmd(options, cmd):
+	ret = {}
+	(ret["err"], ret["out"], _) = run_command(options, cmd)
+	ret["out"] = "".join([i for i in ret["out"] if i is not None])
+	return ret
+
+
+# check if device exist and is block device
+def is_block_device(dev):
+	if not os.path.exists(dev):
+		fail_usage("Failed: device \"" + dev + "\" does not exist")
+	if not stat.S_ISBLK(os.stat(dev).st_mode):
+		fail_usage("Failed: device \"" + dev + "\" is not a block device")
+
+
+# cancel registration
+def preempt_abort(options, host, dev):
+	cmd = options["--sg_persist-path"] + " -n -o -A -T 5 -K " + host + " -S " + options["--key"] + " -d " + dev
+	return not bool(run_cmd(options, cmd)["err"])
+
+
+def reset_dev(options, dev):
+	return run_cmd(options, options["--sg_turs-path"] + " " + dev)["err"]
+
+
+def register_dev(options, dev):
+	dev = os.path.realpath(dev)
+	if re.search(r"^dm", dev[5:]):
+		for slave in get_mpath_slaves(dev):
+			register_dev(options, slave)
+		return True
+	reset_dev(options, dev)
+	cmd = options["--sg_persist-path"] + " -n -o -I -S " + options["--key"] + " -d " + dev
+	cmd += " -Z" if "--aptpl" in options else ""
+	#cmd return code != 0 but registration can be successful
+	return not bool(run_cmd(options, cmd)["err"])
+
+
+def reserve_dev(options, dev):
+	cmd = options["--sg_persist-path"] + " -n -o -R -T 5 -K " + options["--key"] + " -d " + dev
+	return not bool(run_cmd(options, cmd)["err"])
+
+
+def get_reservation_key(options, dev):
+	cmd = options["--sg_persist-path"] + " -n -i -r -d " + dev
+	out = run_cmd(options, cmd)
+	if out["err"]:
+		fail_usage("Cannot get reservation key")
+	match = re.search(r"\s+key=0x(\S+)\s+", out["out"], re.IGNORECASE)
+	return match.group(1) if match else None
+
+
+def get_registration_keys(options, dev):
+	keys = []
+	cmd = options["--sg_persist-path"] + " -n -i -k -d " + dev
+	out = run_cmd(options, cmd)
+	if out["err"]:
+		fail_usage("Cannot get registration keys")
+	for line in out["out"].split("\n"):
+		match = re.search(r"\s+0x(\S+)\s*", line)
+		if match:
+			keys.append(match.group(1))
+	return keys
+
+
+def get_cluster_id(options):
+	cmd = options["--corosync-cmap-path"] + " totem.cluster_name"
+
+	match = re.search(r"\(str\) = (\S+)\n", run_cmd(options, cmd)["out"])
+	return hashlib.md5(match.group(1)).hexdigest() if match else fail_usage("Failed: cannot get cluster name")
+
+
+def get_node_id(options):
+	cmd = options["--corosync-cmap-path"] + " nodelist."
+
+	match = re.search(r".(\d).ring._addr \(str\) = " + options["--nodename"] + "\n", run_cmd(options, cmd)["out"])
+	return match.group(1) if match else fail_usage("Failed: unable to parse output of corosync-cmapctl or node does not exist")
+
+
+def generate_key(options):
+	return "%.4s%.4d" % (get_cluster_id(options), int(get_node_id(options)))
+
+
+# save node key to file
+def set_key(options):
+	file_path = options["store_path"] + ".key"
+	if not os.path.isdir(os.path.dirname(options["store_path"])):
+		os.makedirs(os.path.dirname(options["store_path"]))
+	try:
+		f = open(file_path, "w")
+	except IOError:
+		fail_usage("Failed: Cannot open file \""+ file_path + "\"")
+	f.write(options["--key"].lower() + "\n")
+	f.close()
+
+
+# read node key from file
+def get_key():
+	file_path = STORE_PATH + ".key"
+	try:
+		f = open(file_path, "r")
+	except IOError:
+		fail_usage("Failed: Cannot open file \""+ file_path + "\"")
+	return f.readline().strip().lower()
+
+
+def dev_write(dev, options):
+	file_path = options["store_path"] + ".dev"
+	if not os.path.isdir(os.path.dirname(options["store_path"])):
+		os.makedirs(os.path.dirname(options["store_path"]))
+	try:
+		f = open(file_path, "a+")
+	except IOError:
+		fail_usage("Failed: Cannot open file \""+ file_path + "\"")
+	out = f.read()
+	if not re.search(r"^" + dev + "\s+", out):
+		f.write(dev + "\n")
+	f.close()
+
+
+def dev_read():
+	file_path = STORE_PATH + ".dev"
+	try:
+		f = open(file_path, "r")
+	except IOError:
+		fail_usage("Failed: Cannot open file \"" + file_path + "\"")
+	# get not empty lines from file
+	devs = [line.strip() for line in f if line.strip()]
+	f.close()
+	return devs
+
+
+def dev_delete(options):
+	file_path = options["store_path"] + ".dev"
+	os.remove(file_path) if os.path.exists(file_path) else None
+
+
+def get_clvm_devices(options):
+	devs = []
+	cmd = options["--vgs-path"] + " " +\
+	"--noheadings " +\
+	"--separator : " +\
+	"--sort pv_uuid " +\
+	"--options vg_attr,pv_name "+\
+	"--config 'global { locking_type = 0 } devices { preferred_names = [ \"^/dev/dm\" ] }'"
+	out = run_cmd(options, cmd)
+	if out["err"]:
+		fail_usage("Failed: Cannot get clvm devices")
+	for line in out["out"].split("\n"):
+		if 'c' in line.split(":")[0]:
+			devs.append(line.split(":")[1])
+	return devs
+
+
+def get_mpath_slaves(dev):
+	if dev[:5] == "/dev/":
+		dev = dev[5:]
+	slaves = [i for i in os.listdir("/sys/block/" + dev + "/slaves/") if i[:1] != "."]
+	if slaves[0][:2] == "dm":
+		slaves = get_mpath_slaves(slaves[0])
+	else:
+		slaves = ["/dev/" + x for x in slaves]
+	return slaves
+
+
+def define_new_opts():
+	all_opt["devices"] = {
+		"getopt" : "d:",
+		"longopt" : "devices",
+		"help" : "-d, --devices=[devices]        List of devices to use for current operation",
+		"required" : "0",
+		"shortdesc" : "List of devices to use for current operation. Devices can \
+be comma-separated list of raw device (eg. /dev/sdc) or device-mapper multipath \
+devices (eg. /dev/dm-3). Each device must support SCSI-3 persistent reservations.",
+		"order": 1
+	}
+	all_opt["nodename"] = {
+		"getopt" : "n:",
+		"longopt" : "nodename",
+		"help" : "-n, --nodename=[nodename]      Name of the node to be fenced",
+		"required" : "0",
+		"shortdesc" : "Name of the node to be fenced. The node name is used to \
+generate the key value used for the current operation. This option will be \
+ignored when used with the -k option.",
+		"order": 1
+	}
+	all_opt["key"] = {
+		"getopt" : "k:",
+		"longopt" : "key",
+		"help" : "-k, --key=[key]                Key to use for the current operation",
+		"required" : "0",
+		"shortdesc" : "Key to use for the current operation. This key should be \
+unique to a node. For the \"on\" action, the key specifies the key use to \
+register the local node. For the \"off\" action, this key specifies the key to \
+be removed from the device(s).",
+		"order": 1
+	}
+	all_opt["aptpl"] = {
+		"getopt" : "a",
+		"longopt" : "aptpl",
+		"help" : "-a, --aptpl                    Use the APTPL flag for registrations",
+		"required" : "0",
+		"shortdesc" : "Use the APTPL flag for registrations. This option is only used for the 'on' action.",
+		"order": 1
+	}
+	all_opt["logfile"] = {
+		"getopt" : ":",
+		"longopt" : "logfile",
+		"help" : "-f, --logfile                  Log output (stdout and stderr) to file",
+		"required" : "0",
+		"shortdesc" : "Log output (stdout and stderr) to file",
+		"order": 5
+	}
+	all_opt["corosync-cmap_path"] = {
+		"getopt" : ":",
+		"longopt" : "corosync-cmap-path",
+		"help" : "--corosync-cmap-path=[path]    Path to corosync-cmapctl binary",
+		"required" : "0",
+		"shortdesc" : "Path to corosync-cmapctl binary",
+		"default" : "@COROSYNC_CMAPCTL_PATH@",
+		"order": 300
+	}
+	all_opt["sg_persist_path"] = {
+		"getopt" : ":",
+		"longopt" : "sg_persist-path",
+		"help" : "--sg_persist-path=[path]       Path to sg_persist binary",
+		"required" : "0",
+		"shortdesc" : "Path to sg_persist binary",
+		"default" : "@SG_PERSIST_PATH@",
+		"order": 300
+	}
+	all_opt["sg_turs_path"] = {
+		"getopt" : ":",
+		"longopt" : "sg_turs-path",
+		"help" : "--sg_turs-path=[path]          Path to sg_turs binary",
+		"required" : "0",
+		"shortdesc" : "Path to sg_turs binary",
+		"default" : "@SG_TURS_PATH@",
+		"order": 300
+	}
+	all_opt["vgs_path"] = {
+		"getopt" : ":",
+		"longopt" : "vgs-path",
+		"help" : "--vgs-path=[path]              Path to vgs binary",
+		"required" : "0",
+		"shortdesc" : "Path to vgs binary",
+		"default" : "@VGS_PATH@",
+		"order": 300
+	}
+
+
+def scsi_check_get_verbose():
+	try:
+		f = open("/etc/sysconfig/watchdog", "r")
+	except IOError:
+		return False
+	match = re.search(r"^\s*verbose=yes", "".join(f.readlines()), re.MULTILINE)
+	f.close()
+	return bool(match)
+
+
+def scsi_check():
+	if len(sys.argv) >= 3 and sys.argv[1] == "repair":
+		return int(sys.argv[2])
+	options = {}
+	options["--sg_turs-path"] = "@SG_TURS_PATH@"
+	options["--sg_persist-path"] = "@SG_PERSIST_PATH@"
+	options["--power-timeout"] = "5"
+	if scsi_check_get_verbose():
+		logging.getLogger().setLevel(logging.DEBUG)
+	devs = dev_read()
+	if not devs:
+		logging.error("No devices found")
+		return 0
+	key = get_key()
+	if not key:
+		logging.error("Key not found")
+		return 0
+	for dev in devs:
+		if key in get_registration_keys(options, dev):
+			logging.debug("key " + key + " registered with device " + dev)
+			return 0
+		else:
+			logging.debug("key " + key + " not registered with device " + dev)
+	logging.debug("key " + key + " registered with any devices")
+	return 2
+
+
+def main():
+
+	atexit.register(atexit_handler)
+
+	device_opt = ["no_login", "no_password", "devices", "nodename", "key",\
+	"aptpl", "fabric_fencing", "on_target", "corosync-cmap_path",\
+	"sg_persist_path", "sg_turs_path", "logfile", "vgs_path"]
+
+	define_new_opts()
+
+	all_opt["delay"]["getopt"] = "H:"
+
+	#fence_scsi_check
+	if os.path.basename(sys.argv[0]) == "fence_scsi_check":
+		sys.exit(scsi_check())
+
+	options = check_input(device_opt, process_input(device_opt), other_conditions=True)
+
+	docs = {}
+	docs["shortdesc"] = "Fence agent for SCSI persistentl reservation"
+	docs["longdesc"] = "fence_scsi is an I/O fencing agent that uses SCSI-3 \
+persistent reservations to control access to shared storage devices. These \
+devices must support SCSI-3 persistent reservations (SPC-3 or greater) as \
+well as the \"preempt-and-abort\" subcommand.\nThe fence_scsi agent works by \
+having each node in the cluster register a unique key with the SCSI \
+devive(s). Once registered, a single node will become the reservation holder \
+by creating a \"write exclusive, registrants only\" reservation on the \
+device(s). The result is that only registered nodes may write to the \
+device(s). When a node failure occurs, the fence_scsi agent will remove the \
+key belonging to the failed node from the device(s). The failed node will no \
+longer be able to write to the device(s). A manual reboot is required."
+	docs["vendorurl"] = ""
+	show_docs(options, docs)
+
+	run_delay(options)
+
+	# backward compatibility layer BEGIN
+	if "--logfile" in options:
+		try:
+			logfile = open(options["--logfile"], 'w')
+			sys.stderr = logfile
+			sys.stdout = logfile
+		except IOError:
+			fail_usage("Failed: Unable to create file " + options["--logfile"])
+	# backward compatibility layer END
+
+	options["store_path"] = STORE_PATH
+
+	# Input control BEGIN
+	stop_after_error = False if options["--action"] == "validate-all" else True
+
+	if not (("--nodename" in options and options["--nodename"])\
+	or ("--key" in options and options["--key"])):
+		fail_usage("Failed: nodename or key is required", stop_after_error)
+
+	if not ("--key" in options and options["--key"]):
+		options["--key"] = generate_key(options)
+
+	if options["--key"] == "0" or not options["--key"]:
+		fail_usage("Failed: key cannot be 0", stop_after_error)
+
+	if options["--action"] == "validate-all":
+		sys.exit(0)
+
+	options["--key"] = options["--key"].lstrip('0')
+
+	if not ("--devices" in options and options["--devices"].split(",")):
+		options["devices"] = get_clvm_devices(options)
+	else:
+		options["devices"] = options["--devices"].split(",")
+
+	if not options["devices"]:
+		fail_usage("Failed: No devices found")
+	# Input control END
+
+	result = fence_action(None, options, set_status, get_status)
+	sys.exit(result)
+
+if __name__ == "__main__":
+	main()
diff --git a/fence/agents/scsi/fence_scsi_check.pl b/fence/agents/scsi/fence_scsi_check.pl
deleted file mode 100644
index 9ecd7a5..0000000
--- a/fence/agents/scsi/fence_scsi_check.pl
+++ /dev/null
@@ -1,170 +0,0 @@
-#!/usr/bin/perl
-
-use POSIX;
-
-################################################################################
-
-my $dev_file = "/var/run/cluster/fence_scsi.dev";
-my $key_file = "/var/run/cluster/fence_scsi.key";
-
-################################################################################
-
-sub log_debug ($)
-{
-    my $time = strftime ("%b %e %T", localtime);
-    my $msg = shift;
-
-    print STDOUT "$time [$0] debug: $msg\n" if ($verbose);
-
-    return;
-}
-
-sub log_error ($)
-{
-    my $time = strftime ("%b %e %T", localtime);
-    my $msg = shift;
-
-    print STDERR "$time [$0] error: $msg\n";
-
-    return;
-}
-
-sub do_reset ($)
-{
-    my $dev = shift;
-
-    my $cmd = "sg_turs $dev";
-    my @out = qx { $cmd 2> /dev/null };
-
-    return;
-}
-
-sub get_registration_keys ($)
-{
-    my $dev = shift;
-    my @keys = ();
-
-    do_reset ($dev);
-
-    my $cmd = "sg_persist -n -i -k -d $dev";
-    my @out = qx { $cmd 2> /dev/null };
-
-    if ($?>>8 != 0) {
-	log_error ("$cmd");
-	exit (0);
-    }
-
-    foreach (@out) {
-	chomp;
-	if (s/^\s+0x//i) {
-	    push (@keys, $_);
-	}
-    }
-
-    return (@keys);
-}
-
-sub get_reservation_keys ($)
-{
-    my $dev = shift;
-    my @keys = ();
-
-    do_reset ($dev);
-
-    my $cmd = "sg_persist -n -i -r -d $dev";
-    my @out = qx { $cmd 2> /dev/null };
-
-    if ($?>>8 != 0) {
-	log_error ("$cmd");
-	exit (0);
-    }
-
-    foreach (@out) {
-	chomp;
-	if (s/^\s+key=0x//i) {
-	    push (@keys, $_);
-	}
-    }
-
-    return (@keys);
-}
-
-sub get_verbose ()
-{
-    open (\*FILE, "</etc/sysconfig/watchdog") or return;
-    chomp (my @opt = <FILE>);
-    close (FILE);
-
-    foreach (@opt) {
-	next if (/^#/);
-	next unless ($_);
-
-	if (/^verbose=yes$/i) {
-	    return (1);
-	}
-    }
-
-    return (0);
-}
-
-sub key_read ()
-{
-    open (\*FILE, "<$key_file") or exit (0);
-    chomp (my $key = <FILE>);
-    close (FILE);
-
-    return ($key);
-}
-
-sub dev_read ()
-{
-    open (\*FILE, "<$dev_file") or exit (0);
-    chomp (my @dev = <FILE>);
-    close (FILE);
-
-    return (@dev);
-}
-
-################################################################################
-
-if ($ARGV[0] =~ /^repair$/i) {
-    exit ($ARGV[1]);
-}
-
-if (-e "/etc/sysconfig/watchdog") {
-    $verbose = get_verbose ();
-}
-
-if (! -e $dev_file) {
-    log_debug ("$dev_file does not exit");
-    exit (0);
-} elsif (-z $dev_file) {
-    log_debug ("$dev_file is empty");
-    exit (0);
-}
-
-if (! -e $key_file) {
-    log_debug ("$key_file does not exist");
-    exit (0);
-} elsif (-z $key_file) {
-    log_debug ("$key_file is empty");
-    exit (0);
-}
-
-my $key = key_read ();
-my @dev = dev_read ();
-
-foreach (@dev) {
-    my @keys = grep { /^$key$/i } get_registration_keys ($_);
-
-    if (scalar (@keys) != 0) {
-	log_debug ("key $key registered with device $_");
-	exit (0);
-    } else {
-	log_debug ("key $key not registered with device $_");
-    }
-}
-
-log_debug ("key $key not registered with any devices");
-
-exit (2);
diff --git a/fence/agents/virsh/Makefile.am b/fence/agents/virsh/Makefile.am
index 0f12744..7dd0fa2 100644
--- a/fence/agents/virsh/Makefile.am
+++ b/fence/agents/virsh/Makefile.am
@@ -10,8 +10,8 @@ sbin_SCRIPTS		= $(TARGET)
 
 man_MANS		= $(TARGET).8
 
+FENCE_TEST_ARGS         = -l test -p test -a test -n 1
+
 include $(top_srcdir)/make/fencebuild.mk
 include $(top_srcdir)/make/fenceman.mk
-
-clean-local: clean-man
-	rm -f $(TARGET)
+include $(top_srcdir)/make/agentpycheck.mk
diff --git a/fence/agents/virsh/fence_virsh.py b/fence/agents/virsh/fence_virsh.py
index 1ec5310..d3dd8fc 100644
--- a/fence/agents/virsh/fence_virsh.py
+++ b/fence/agents/virsh/fence_virsh.py
@@ -1,13 +1,16 @@
-#!/usr/bin/python
+#!/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, pexpect, exceptions
+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"
@@ -20,12 +23,12 @@ def get_name_or_uuid(options):
 
 def get_outlets_status(conn, options):
 	if options.has_key("--use-sudo"):
-		prefix = SUDO_PATH + " "
+		prefix = options["--sudo-path"] + " "
 	else:
 		prefix = ""
 
 	conn.sendline(prefix + "virsh list --all")
-	conn.log_expect(options, options["--command-prompt"], int(options["--shell-timeout"]))
+	conn.log_expect(options["--command-prompt"], int(options["--shell-timeout"]))
 
 	result = {}
 
@@ -33,19 +36,20 @@ def get_outlets_status(conn, options):
 	fa_status = 0
 
 	for line in conn.before.splitlines():
-		domain = re.search("^\s*(\S+)\s+(\S+)\s+(\S+).*$", line)
+		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")):
+		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"))
+			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 = SUDO_PATH + " " if options.has_key("--use-sudo") else ""
+	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, options["--command-prompt"], int(options["--shell-timeout"]))
+	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"]:
@@ -56,24 +60,25 @@ def get_power_status(conn, options):
 	return "off"
 
 def set_power_status(conn, options):
-	prefix = 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))
+	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, options["--command-prompt"], int(options["--power-timeout"]))
+	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"]
 
 	atexit.register(atexit_handler)
 
 	all_opt["secure"]["default"] = "1"
-	all_opt["cmd_prompt"]["default"] = [ "\[EXPECT\]#\ " ]
-	all_opt["ssh_options"]["default"] = "-t '/bin/bash -c \"PS1=\[EXPECT\]#\  /bin/bash --noprofile --norc\"'"
+	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 = {}
 	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. \
@@ -88,14 +93,8 @@ must allow ssh login in your sshd_config."
 	## Operate the fencing device
 	conn = fence_login(options)
 	result = fence_action(conn, options, set_power_status, get_power_status, get_outlets_status)
-
-	## Logout from system
-	try:
-		conn.sendline("quit")
-		conn.close()
-	except:
-		pass
-
+	fence_logout(conn, "quit")
 	sys.exit(result)
+
 if __name__ == "__main__":
 	main()
diff --git a/fence/agents/vixel/Makefile.am b/fence/agents/vixel/Makefile.am
deleted file mode 100644
index 3159e50..0000000
--- a/fence/agents/vixel/Makefile.am
+++ /dev/null
@@ -1,17 +0,0 @@
-MAINTAINERCLEANFILES	= Makefile.in
-
-TARGET			= fence_vixel
-
-SRC			= $(TARGET).pl
-
-EXTRA_DIST		= $(SRC)
-
-sbin_SCRIPTS		= $(TARGET)
-
-man_MANS		= $(TARGET).8
-
-include $(top_srcdir)/make/fencebuild.mk
-include $(top_srcdir)/make/fencemanperl.mk
-
-clean-local: clean-man
-	rm -f $(TARGET)
diff --git a/fence/agents/vixel/fence_vixel.pl b/fence/agents/vixel/fence_vixel.pl
deleted file mode 100644
index 2080909..0000000
--- a/fence/agents/vixel/fence_vixel.pl
+++ /dev/null
@@ -1,267 +0,0 @@
-#!/usr/bin/perl
-
-use Getopt::Std;
-use Net::Telnet ();
-
-my $ME = $0;
-
-END {
-  defined fileno STDOUT or return;
-  close STDOUT and return;
-  warn "$ME: failed to close standard output: $!\n";
-  $? ||= 1;
-}
-
-# Get the program name from $0 and strip directory names
-$_=$0;
-s/.*\///;
-my $pname = $_;
-
-# WARNING!! Do not add code bewteen "#BEGIN_VERSION_GENERATION" and
-# "#END_VERSION_GENERATION"  It is generated by the Makefile
-
-#BEGIN_VERSION_GENERATION
-$RELEASE_VERSION="";
-$REDHAT_COPYRIGHT="";
-$BUILD_DATE="";
-#END_VERSION_GENERATION
-
-
-sub usage 
-{
-    print "Usage:\n\n"; 
-    print "$pname [options]\n\n";
-    print "Options:\n";
-    print "  -a <ip>          IP address or hostname of switch\n";
-    print "  -h               Usage\n";
-    print "  -o metadata      print XML metadata for fence agent\n";
-    print "  -n <num>         Port number to disable\n";
-    print "  -p <string>      Password for login\n";
-    print "  -S <path>        Script to run to retrieve login password\n";
-    print "  -V               version\n\n";
-
-    exit 0;
-}
-
-sub fail
-{
-  ($msg) = @_;
-  print $msg."\n" unless defined $opt_q;
-  $t->close if defined $t;
-  exit 1;
-}
-
-sub fail_usage
-{
-  ($msg) = @_;
-  print STDERR $msg."\n" if $msg;
-  print STDERR "Please use '-h' for usage.\n";
-  exit 1;
-}
-
-sub version
-{
-  print "$pname $RELEASE_VERSION $BUILD_DATE\n";
-  print "$REDHAT_COPYRIGHT\n" if ( $REDHAT_COPYRIGHT );
-
-  exit 0;
-}
-
-sub print_metadata
-{
-print '<?xml version="1.0" ?>
-<resource-agent name="fence_vixel" shortdesc="I/O Fencing agent for Vixel FC switches" >
-<longdesc>
-fence_vixel is an I/O Fencing agent which can be used with Vixel FC switches. It logs into a Vixel switch via telnet and removes the specified port from the zone. Removing the zone access from the port disables the port from being able to access the storage.
-
-After a fence operation has taken place the fenced machine can no longer connect to the Vixel FC switch. When the fenced machine is ready to be brought back into the GFS cluster (after reboot) the port on the Vixel FC switch needs to be enabled. In order to do this, log into the Vixel FC switch. Then go to:
-
-config->zones->config [port] [comma-separated-list-of-ports-in-the-zone]
-
-Then apply. Consult the Vixel manual for details.
-</longdesc>
-<vendor-url>http://www.emulex.com</vendor-url>
-<parameters>
-        <parameter name="ipaddr" unique="1" required="1">
-                <getopt mixed="-a [ip]" />
-                <content type="string"  />
-                <shortdesc lang="en">IP Address or Hostname</shortdesc>
-        </parameter>
-        <parameter name="passwd" unique="1" required="0">
-                <getopt mixed="-p [password]" />
-                <content type="string"  />
-                <shortdesc lang="en">Login password or passphrase</shortdesc>
-        </parameter>
-        <parameter name="passwd_script" unique="1" required="0">
-                <getopt mixed="-S [script]" />
-                <content type="string"  />
-                <shortdesc lang="en">Script to retrieve password</shortdesc>
-        </parameter>
-        <parameter name="port" unique="1" required="1">
-                <getopt mixed="-n [id]" />
-                <content type="string"  />
-                <shortdesc lang="en">Physical plug number or name of virtual machine</shortdesc>
-        </parameter>
-        <parameter name="help" unique="1" required="0">
-                <getopt mixed="-h" />           
-                <content type="string"  />
-                <shortdesc lang="en">Display help and exit</shortdesc>                    
-        </parameter>
-</parameters>
-<actions>
-        <action name="metadata" />
-</actions>
-</resource-agent>
-';
-}
-
-
-if (@ARGV > 0) {
-    getopts("a:hn:p:S:Vo:") || fail_usage ;
-
-    usage if defined $opt_h;
-    version if defined $opt_V;
-
-    fail_usage "Unknown parameter." if (@ARGV > 0);
-
-    if ((defined $opt_o) && ($opt_o =~ /metadata/i)) {
-        print_metadata();
-        exit 0;
-    }
-
-    fail_usage "No '-a' flag specified." unless defined $opt_a;
-
-	if (defined $opt_S) {
-		$pwd_script_out = `$opt_S`;
-		chomp($pwd_script_out);
-		if ($pwd_script_out) {
-			$opt_p = $pwd_script_out;
-		}
-	}
-
-    fail_usage "No '-p' or '-S' flag specified." unless defined $opt_p;
-    fail_usage "No '-n' flag specified." unless defined $opt_n;
-
-} else {
-    get_options_stdin();
-
-    fail "failed: no IP address for the Vixel." unless defined $opt_a;
-
-	if (defined $opt_S) {
-		$pwd_script_out = `$opt_S`;
-		chomp($pwd_script_out);
-		if ($pwd_script_out) {
-			$opt_p = $pwd_script_out;
-		}
-	}
-
-    fail "failed: no password provided." unless defined $opt_p;
-    fail "failed: no port number specified." unless defined $opt_n;
-}
-
-#
-# Set up and log in
-#
-
-$t = new Net::Telnet;
-
-$t->open($opt_a);
-
-$t->waitfor('/assword:/');
-
-$t->print($opt_p);
-
-($out, $match)= $t->waitfor(Match => '/\>/', Match => '/assword:/');
-
-if ($match =~ /assword:/) {
-  fail "failed: incorrect password\n";
-} elsif ( $match !~ />/ ) {
-  fail "failed: timed out waiting for prompt\n";
-}
- 
-$t->print("config");
-
-$t->waitfor('/\(config\)\>/');
-
-$t->print("zone");
-
-$t->waitfor('/\(config\/zone\)\>/');
-
-#
-# Do the command
-#
-
-$cmd = "config $opt_n \"\"";
-$t->print($cmd);
-
-$t->waitfor('/\(config\/zone\)\>/');
-
-$t->print("apply");
-
-($text, $match) = $t->waitfor('/\>/');
-if ($text !~ /[Oo][Kk]/) {
-	fail "failed: error from switch\n";
-}
-
-$t->print("exit");
-
-print "success: zonedisable $opt_n\n";
-exit 0;
-
-
-sub get_options_stdin
-{
-	my $opt;
-	my $line = 0;
-
-	while( defined($in = <>) )
-	{
-		$_ = $in;
-		chomp;
-
-		# strip leading and trailing whitespace
-		s/^\s*//;
-		s/\s*$//;
-
-		# skip comments
-		next if /^#/;
-
-		$line+=1;
-		$opt=$_;
-		next unless $opt;
-
-		($name,$val)=split /\s*=\s*/, $opt;
-
-		if ( $name eq "" ) {
-			print("parse error: illegal name in option $line\n");
-			exit 2;
-		} 
-
-		# DO NOTHING -- this field is used by fenced
-		elsif ($name eq "agent" ) { }
-
-		# FIXME -- depricated.  use "port" instead.
-		elsif ($name eq "fm" ) {
-			(my $dummy,$opt_n) = split /\s+/,$val;
-			print STDERR "Depricated \"fm\" entry detected. Refer to man page.\n";
-		} 
-		elsif ($name eq "ipaddr" ) 
-		{
-			$opt_a = $val;
-		} 
-		elsif ($name eq "name" ) { }
-		elsif ($name eq "passwd" ) 
-		{
-			$opt_p = $val;
-		}
-		elsif ($name eq "passwd_script" )
-		{
-			$opt_S = $val;
-		} 
-		elsif ($name eq "port" ) 
-		{
-			$opt_n = $val;
-		} 
-	}
-}
-
diff --git a/fence/agents/vmware/Makefile.am b/fence/agents/vmware/Makefile.am
index 9f41c0d..e0cd910 100644
--- a/fence/agents/vmware/Makefile.am
+++ b/fence/agents/vmware/Makefile.am
@@ -10,8 +10,7 @@ sbin_SCRIPTS		= $(TARGET)
 
 man_MANS		= fence_vmware.8
 
+FENCE_TEST_ARGS         = -l test -p test -a test -n 1
+
 include $(top_srcdir)/make/fencebuild.mk
 include $(top_srcdir)/make/fenceman.mk
-
-clean-local: clean-man
-	rm -f $(TARGET)
diff --git a/fence/agents/vmware/fence_vmware.py b/fence/agents/vmware/fence_vmware.py
index dc4ef0f..e252fe3 100644
--- a/fence/agents/vmware/fence_vmware.py
+++ b/fence/agents/vmware/fence_vmware.py
@@ -1,4 +1,4 @@
-#!/usr/bin/python
+#!/usr/bin/python -tt
 
 #
 # The Following agent has been tested on:
@@ -22,9 +22,12 @@
 #	VMware vCenter 4.0.0
 #
 
-import sys, re, pexpect, exceptions
+import sys, re, pexpect
+import logging
+import atexit
 sys.path.append("@FENCEAGENTSLIBDIR@")
 from fencing import *
+from fencing import fail, fail_usage, EC_TIMED_OUT, run_delay
 
 #BEGIN_VERSION_GENERATION
 RELEASE_VERSION="VMware Agent using VI Perl API and/or VIX vmrun command"
@@ -69,34 +72,34 @@ def dsv_split(dsv_str):
 	tmp_str = ""
 
 	for x in dsv_str:
-		if (status==0):
-			if (x==delimiter_c):
+		if status == 0:
+			if x == delimiter_c:
 				res.append(tmp_str)
 				tmp_str = ""
-			elif (x==escape_c):
+			elif x == escape_c:
 				status = 1
 			else:
 				tmp_str += x
-		elif (status==1):
-			if (x==delimiter_c):
+		elif status == 1:
+			if x == delimiter_c:
 				tmp_str += delimiter_c
-			elif (x==escape_c):
+			elif x == escape_c:
 				tmp_str += escape_c
 			else:
 				tmp_str += escape_c+x
 			status = 0
 
-	if (tmp_str != ""):
+	if tmp_str != "":
 		res.append(tmp_str)
 
 	return res
 
 # Quote string for proper existence in quoted string used for pexpect.run function
 # Ex. test'this will return test'\''this. So pexpect run will really pass ' to argument
-def quote_for_run(str):
+def quote_for_run(text):
 	dstr = ''
 
-	for c in str:
+	for c in text:
 		if c == r"'":
 			dstr += "'\\''"
 		else:
@@ -108,37 +111,32 @@ def quote_for_run(str):
 def vmware_prepare_command(options, add_login_params, additional_params):
 	res = options["--exec"]
 
-	if (add_login_params):
-		if (vmware_internal_type==VMWARE_TYPE_ESX):
+	if add_login_params:
+		if vmware_internal_type == VMWARE_TYPE_ESX:
 			res += " --server '%s' --username '%s' --password '%s' "% (quote_for_run(options["--ip"]),
 										quote_for_run(options["--username"]),
 										quote_for_run(options["--password"]))
-		elif (vmware_internal_type==VMWARE_TYPE_SERVER2):
+		elif vmware_internal_type == VMWARE_TYPE_SERVER2:
 			res += " -h 'https://%s/sdk' -u '%s' -p '%s' -T server "% (quote_for_run(options["--ip"]),
 										quote_for_run(options["--username"]),
 										quote_for_run(options["--password"]))
-		elif (vmware_internal_type==VMWARE_TYPE_SERVER1):
+		elif vmware_internal_type == VMWARE_TYPE_SERVER1:
 			host_name_array = options["--ip"].split(':')
 
 			res += " -h '%s' -u '%s' -p '%s' -T server1 "% (quote_for_run(host_name_array[0]),
 								     quote_for_run(options["--username"]),
 								     quote_for_run(options["--password"]))
-			if (len(host_name_array)>1):
+			if len(host_name_array) > 1:
 				res += "-P '%s' "% (quote_for_run(host_name_array[1]))
 
-	if ((options.has_key("--vmware-datacenter")) and (vmware_internal_type==VMWARE_TYPE_ESX)):
+	if options.has_key("--vmware-datacenter") and vmware_internal_type == VMWARE_TYPE_ESX:
 		res += "--datacenter '%s' "% (quote_for_run(options["--vmware-datacenter"]))
 
-	if (additional_params != ""):
+	if additional_params != "":
 		res += additional_params
 
 	return res
 
-# Log message if user set verbose option
-def vmware_log(options, message):
-	if options["log"] >= LOG_MODE_VERBOSE:
-		options["debug_fh"].write(message+"\n")
-
 # Run command with timeout and parameters. Internaly uses vmware_prepare_command. Returns string
 # with output from vmrun command. If something fails (command not found, exit code is not 0), fail_usage
 # function is called (and never return).
@@ -146,17 +144,18 @@ def vmware_run_command(options, add_login_params, additional_params, additional_
 	command = vmware_prepare_command(options, add_login_params, additional_params)
 
 	try:
-		vmware_log(options, command)
+		logging.debug("%s\n", command)
 
-		(res_output, res_code) = pexpect.run(command, int(options["--shell-timeout"])+int(options["--login-timeout"])+additional_timeout, True)
+		(res_output, res_code) = pexpect.run(command,
+				int(options["--shell-timeout"]) + int(options["--login-timeout"]) + additional_timeout, True)
 
-		if (res_code==None):
+		if res_code == None:
 			fail(EC_TIMED_OUT)
-		if ((res_code!=0) and (add_login_params)):
-			vmware_log(options, res_output)
+		if res_code != 0 and add_login_params:
+			logging.debug("%s\n", res_output)
 			fail_usage("%s returned %s"% (options["--exec"], res_output))
 		else:
-			vmware_log(options, res_output)
+			logging.debug("%s\n", res_output)
 
 	except pexpect.ExceptionPexpect:
 		fail_usage("Cannot run command %s"% (options["--exec"]))
@@ -165,11 +164,12 @@ def vmware_run_command(options, add_login_params, additional_params, additional_
 
 # Get outlet list with status as hash table. If you will use add_vm_name, only VM with vmname is
 # returned. This is used in get_status function
-def vmware_get_outlets_vi(conn, options, add_vm_name):
+def vmware_get_outlets_vi(options, add_vm_name):
 	outlets = {}
 
-	if (add_vm_name):
-		all_machines = vmware_run_command(options, True, ("--operation status --vmname '%s'"% (quote_for_run(options["--plug"]))), 0)
+	if add_vm_name:
+		all_machines = vmware_run_command(options, True,
+				("--operation status --vmname '%s'"% (quote_for_run(options["--plug"]))), 0)
 	else:
 		all_machines = vmware_run_command(options, True, "--operation list", int(options["--power-timeout"]))
 
@@ -177,64 +177,70 @@ def vmware_get_outlets_vi(conn, options, add_vm_name):
 
 	for machine in all_machines_array:
 		machine_array = dsv_split(machine)
-		if (len(machine_array) == 4):
-			if (machine_array[0] in outlets):
+		if len(machine_array) == 4:
+			if machine_array[0] in outlets:
 				fail_usage("Failed. More machines with same name %s found!"%(machine_array[0]))
 
-			if (vmware_disconnected_hack):
+			if vmware_disconnected_hack:
 				outlets[machine_array[0]] = ("", (
 						((machine_array[2].lower() in ["poweredon"]) and
-						 (machine_array[3].lower()=="connected"))
+						 (machine_array[3].lower() == "connected"))
 						and "on" or "off"))
 			else:
 				outlets[machine_array[0]] = ("", ((machine_array[2].lower() in ["poweredon"]) and "on" or "off"))
 	return outlets
 
 # Get outlet list with status as hash table.
-def vmware_get_outlets_vix(conn, options):
+def vmware_get_outlets_vix(options):
 	outlets = {}
 
 	running_machines = vmware_run_command(options, True, "list", 0)
 	running_machines_array = running_machines.splitlines()[1:]
 
-	if (vmware_internal_type==VMWARE_TYPE_SERVER2):
+	if vmware_internal_type == VMWARE_TYPE_SERVER2:
 		all_machines = vmware_run_command(options, True, "listRegisteredVM", 0)
 		all_machines_array = all_machines.splitlines()[1:]
-	elif (vmware_internal_type==VMWARE_TYPE_SERVER1):
+	elif vmware_internal_type == VMWARE_TYPE_SERVER1:
 		all_machines_array = running_machines_array
 
 	for machine in all_machines_array:
-		if (machine!=""):
+		if machine != "":
 			outlets[machine] = ("", ((machine in running_machines_array) and "on" or "off"))
 
 	return outlets
 
 def get_outlets_status(conn, options):
-	if (vmware_internal_type==VMWARE_TYPE_ESX):
-		return vmware_get_outlets_vi(conn, options, False)
-	if ((vmware_internal_type==VMWARE_TYPE_SERVER1) or (vmware_internal_type==VMWARE_TYPE_SERVER2)):
-		return vmware_get_outlets_vix(conn, options)
+	del conn
+
+	if vmware_internal_type == VMWARE_TYPE_ESX:
+		return vmware_get_outlets_vi(options, False)
+	if vmware_internal_type == VMWARE_TYPE_SERVER1 or vmware_internal_type == VMWARE_TYPE_SERVER2:
+		return vmware_get_outlets_vix(options)
 
 def get_power_status(conn, options):
-	if (vmware_internal_type==VMWARE_TYPE_ESX):
-		outlets = vmware_get_outlets_vi(conn, options, True)
+	if vmware_internal_type == VMWARE_TYPE_ESX:
+		outlets = vmware_get_outlets_vi(options, True)
 	else:
 		outlets = get_outlets_status(conn, options)
 
-	if ((vmware_internal_type==VMWARE_TYPE_SERVER2) or (vmware_internal_type==VMWARE_TYPE_ESX)):
-		if (not (options["--plug"] in outlets)):
+	if vmware_internal_type == VMWARE_TYPE_SERVER2 or vmware_internal_type == VMWARE_TYPE_ESX:
+		if not options["--plug"] in outlets:
 			fail_usage("Failed: You have to enter existing name of virtual machine!")
 		else:
 			return outlets[options["--plug"]][1]
-	elif (vmware_internal_type==VMWARE_TYPE_SERVER1):
-		return ((options["--plug"] in outlets) and "on" or "off")
+	elif vmware_internal_type == VMWARE_TYPE_SERVER1:
+		return (options["--plug"] in outlets) and "on" or "off"
 
 def set_power_status(conn, options):
-	if (vmware_internal_type==VMWARE_TYPE_ESX):
-		additional_params = "--operation %s --vmname '%s'"% ((options["--action"]=="on" and "on" or "off"), quote_for_run(options["--plug"]))
-	elif ((vmware_internal_type==VMWARE_TYPE_SERVER1) or (vmware_internal_type==VMWARE_TYPE_SERVER2)):
-		additional_params = "%s '%s'"% ((options["--action"]=="on" and "start" or "stop"), quote_for_run(options["--plug"]))
-		if (options["--action"]=="off"):
+	del conn
+
+	if vmware_internal_type == VMWARE_TYPE_ESX:
+		additional_params = "--operation %s --vmname '%s'" % \
+				((options["--action"] == "on" and "on" or "off"), quote_for_run(options["--plug"]))
+	elif vmware_internal_type == VMWARE_TYPE_SERVER1 or vmware_internal_type == VMWARE_TYPE_SERVER2:
+		additional_params = "%s '%s'" % \
+				((options["--action"] == "on" and "start" or "stop"), quote_for_run(options["--plug"]))
+		if options["--action"] == "off":
 			additional_params += " hard"
 
 	vmware_run_command(options, True, additional_params, int(options["--power-timeout"]))
@@ -242,14 +248,14 @@ def set_power_status(conn, options):
 # Returns True, if user uses supported vmrun version (currently >=2.0.0) otherwise False.
 def vmware_is_supported_vmrun_version(options):
 	vmware_help_str = vmware_run_command(options, False, "", 0)
-	version_re = re.search("vmrun version (\d\.(\d[\.]*)*)", vmware_help_str.lower())
-	if (version_re==None):
+	version_re = re.search(r"vmrun version (\d\.(\d[\.]*)*)", vmware_help_str.lower())
+	if version_re == None:
 		return False   # Looks like this "vmrun" is not real vmrun
 
 	version_array = version_re.group(1).split(".")
 
 	try:
-		if (int(version_array[0]) < VMRUN_MINIMUM_REQUIRED_VERSION):
+		if int(version_array[0]) < VMRUN_MINIMUM_REQUIRED_VERSION:
 			return False
 	except Exception:
 		return False
@@ -263,24 +269,24 @@ def vmware_check_vmware_type(options):
 
 	options["--vmware_type"] = options["--vmware_type"].lower()
 
-	if (options["--vmware_type"]=="esx"):
+	if options["--vmware_type"] == "esx":
 		vmware_internal_type = VMWARE_TYPE_ESX
-		if (not options.has_key("--exec")):
+		if not options.has_key("--exec"):
 			options["--exec"] = VMHELPER_COMMAND
-	elif (options["--vmware_type"]=="server2"):
+	elif options["--vmware_type"] == "server2":
 		vmware_internal_type = VMWARE_TYPE_SERVER2
-		if (not options.has_key("--exec")):
+		if not options.has_key("--exec"):
 			options["--exec"] = VMRUN_COMMAND
-	elif (options["--vmware_type"]=="server1"):
+	elif options["--vmware_type"] == "server1":
 		vmware_internal_type = VMWARE_TYPE_SERVER1
-		if (not options.has_key("--exec")):
+		if not options.has_key("--exec"):
 			options["--exec"] = VMRUN_COMMAND
 	else:
 		fail_usage("vmware_type can be esx,server2 or server1!")
 
 # Main agent method
 def main():
-	device_opt = [ "ipaddr", "login", "passwd", "secure",
+	device_opt = ["ipaddr", "login", "passwd", "secure",
 		       "exec", "vmware_type", "vmware_datacenter"]
 
 	atexit.register(atexit_handler)
@@ -290,7 +296,7 @@ def main():
 
 	options = check_input(device_opt, process_input(device_opt))
 
-	docs = { }
+	docs = {}
 	docs["shortdesc"] = "Fence agent for VMWare"
 	docs["longdesc"] = "fence_vmware is an I/O Fencing agent \
 which can be used with the VMware ESX, VMware ESXi or VMware Server \
@@ -316,17 +322,20 @@ This agent supports only vmrun from version 2.0.0 (VIX API 1.6.0)."
 	docs["vendorurl"] = "http://www.vmware.com"
 	show_docs(options, docs)
 
+	run_delay(options)
+
 	# Check vmware type and set path
 	vmware_check_vmware_type(options)
 
 	# Test user vmrun command version
-	if ((vmware_internal_type==VMWARE_TYPE_SERVER1) or (vmware_internal_type==VMWARE_TYPE_SERVER2)):
-		if (not (vmware_is_supported_vmrun_version(options))):
-			fail_usage("Unsupported version of vmrun command! You must use at least version %d!"%(VMRUN_MINIMUM_REQUIRED_VERSION))
+	if vmware_internal_type == VMWARE_TYPE_SERVER1 or vmware_internal_type == VMWARE_TYPE_SERVER2:
+		if not vmware_is_supported_vmrun_version(options):
+			fail_usage("Unsupported version of vmrun command! You must use at least version %d!" %
+					(VMRUN_MINIMUM_REQUIRED_VERSION))
 
 	# Operate the fencing device
 	result = fence_action(None, options, set_power_status, get_power_status, get_outlets_status)
-	
+
 	sys.exit(result)
 
 if __name__ == "__main__":
diff --git a/fence/agents/vmware_soap/Makefile.am b/fence/agents/vmware_soap/Makefile.am
index 8e4e061..15e6748 100644
--- a/fence/agents/vmware_soap/Makefile.am
+++ b/fence/agents/vmware_soap/Makefile.am
@@ -10,8 +10,8 @@ sbin_SCRIPTS		= $(TARGET)
 
 man_MANS		= $(TARGET).8
 
+FENCE_TEST_ARGS         = -l test -p test -a test -n 1
+
 include $(top_srcdir)/make/fencebuild.mk
 include $(top_srcdir)/make/fenceman.mk
-
-clean-local: clean-man
-	rm -f $(TARGET)
+include $(top_srcdir)/make/agentpycheck.mk
diff --git a/fence/agents/vmware_soap/fence_vmware_soap.py b/fence/agents/vmware_soap/fence_vmware_soap.py
index 776273e..e47f11e 100644
--- a/fence/agents/vmware_soap/fence_vmware_soap.py
+++ b/fence/agents/vmware_soap/fence_vmware_soap.py
@@ -1,12 +1,18 @@
-#!/usr/bin/python
+#!/usr/bin/python -tt
 
-import sys, exceptions, time
+import sys
 import shutil, tempfile, suds
+import logging, requests
+import atexit
 sys.path.append("@FENCEAGENTSLIBDIR@")
 
 from suds.client import Client
 from suds.sudsobject import Property
+from suds.transport.http import HttpAuthenticated
+from suds.transport import Reply, TransportError
 from fencing import *
+from fencing import fail, fail_usage, EC_STATUS, EC_LOGIN_DENIED, EC_INVALID_PRIVILEGES, EC_WAITING_ON, EC_WAITING_OFF
+from fencing import run_delay
 
 #BEGIN_VERSION_GENERATION
 RELEASE_VERSION="New VMWare Agent - test release on steroids"
@@ -14,24 +20,45 @@ REDHAT_COPYRIGHT=""
 BUILD_DATE="April, 2011"
 #END_VERSION_GENERATION
 
+options_global = None
+conn_global = None
+
+class RequestsTransport(HttpAuthenticated):
+	def __init__(self, **kwargs):
+		self.cert = kwargs.pop('cert', None)
+		self.verify = kwargs.pop('verify', True)
+		self.session = requests.Session()
+		# super won't work because not using new style class
+		HttpAuthenticated.__init__(self, **kwargs)
+
+	def send(self, request):
+		self.addcredentials(request)
+		resp = self.session.post(request.url, data=request.message, headers=request.headers, cert=self.cert, verify=self.verify)
+		result = Reply(resp.status_code, resp.headers, resp.content)
+		return result
+
 def soap_login(options):
-	if options["-o"] in ["off", "reboot"]:
-		time.sleep(int(options["--delay"]))
+	run_delay(options)
 
-	if options.has_key("--ssl"):
+	if options.has_key("--ssl") or options.has_key("--ssl-secure") or options.has_key("--ssl-insecure"):
+		if options.has_key("--ssl-insecure"):
+			verify = False
+		else:
+			verify = True
 		url = "https://"
 	else:
+		verify = False
 		url = "http://"
-	
+
 	url += options["--ip"] + ":" + str(options["--ipport"]) + "/sdk"
 
 	tmp_dir = tempfile.mkdtemp()
 	tempfile.tempdir = tmp_dir
 	atexit.register(remove_tmp_dir, tmp_dir)
-	
+
 	try:
-		conn = Client(url + "/vimService.wsdl")
-		conn.set_options(location = url)
+		headers = {"Content-Type" : "text/xml;charset=UTF-8", "SOAPAction" : ""}
+		conn = Client(url + "/vimService.wsdl", location=url, transport=RequestsTransport(verify=verify), headers=headers)
 
 		mo_ServiceInstance = Property('ServiceInstance')
 		mo_ServiceInstance._type = 'ServiceInstance'
@@ -39,9 +66,11 @@ def soap_login(options):
 		mo_SessionManager = Property(ServiceContent.sessionManager.value)
 		mo_SessionManager._type = 'SessionManager'
 
-		SessionManager = conn.service.Login(mo_SessionManager, options["--username"], options["--password"])
-	except Exception, ex:
-		fail(EC_LOGIN_DENIED)	
+		conn.service.Login(mo_SessionManager, options["--username"], options["--password"])
+	except requests.exceptions.SSLError, ex:
+		fail_usage("Server side certificate verification failed")
+	except Exception:
+		fail(EC_LOGIN_DENIED)
 
 	options["ServiceContent"] = ServiceContent
 	options["mo_SessionManager"] = mo_SessionManager
@@ -71,7 +100,8 @@ def get_power_status(conn, options):
 	mo_PropertyCollector = Property(options["ServiceContent"].propertyCollector.value)
 	mo_PropertyCollector._type = 'PropertyCollector'
 
-	ContainerView = conn.service.CreateContainerView(mo_ViewManager, recursive = 1, container = mo_RootFolder, type = ['VirtualMachine'])
+	ContainerView = conn.service.CreateContainerView(mo_ViewManager, recursive=1,
+			container=mo_RootFolder, type=['VirtualMachine'])
 	mo_ContainerView = Property(ContainerView.value)
 	mo_ContainerView._type = "ContainerView"
 
@@ -83,7 +113,7 @@ def get_power_status(conn, options):
 
 	objSpec = conn.factory.create('ns0:ObjectSpec')
 	objSpec.obj = mo_ContainerView
-	objSpec.selectSet = [ FolderTraversalSpec ]
+	objSpec.selectSet = [FolderTraversalSpec]
 	objSpec.skip = True
 
 	propSpec = conn.factory.create('ns0:PropertySpec')
@@ -92,21 +122,21 @@ def get_power_status(conn, options):
 	propSpec.type = "VirtualMachine"
 
 	propFilterSpec = conn.factory.create('ns0:PropertyFilterSpec')
-	propFilterSpec.propSet = [ propSpec ]
-	propFilterSpec.objectSet = [ objSpec ]
+	propFilterSpec.propSet = [propSpec]
+	propFilterSpec.objectSet = [objSpec]
 
 	try:
 		raw_machines = conn.service.RetrievePropertiesEx(mo_PropertyCollector, propFilterSpec)
-	except Exception, ex:
+	except Exception:
 		fail(EC_STATUS)
 
 	(machines, uuid, mappingToUUID) = process_results(raw_machines, {}, {}, {})
 
         # Probably need to loop over the ContinueRetreive if there are more results after 1 iteration.
-	while (hasattr(raw_machines, 'token') == True):
+	while hasattr(raw_machines, 'token'):
 		try:
 			raw_machines = conn.service.ContinueRetrievePropertiesEx(mo_PropertyCollector, raw_machines.token)
-		except Exception, ex:
+		except Exception:
 			fail(EC_STATUS)
 		(more_machines, more_uuid, more_mappingToUUID) = process_results(raw_machines, {}, {}, {})
 		machines.update(more_machines)
@@ -119,28 +149,28 @@ 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)
 				mo_SearchIndex._type = "SearchIndex"
-			
+
 				vm = conn.service.FindByInventoryPath(mo_SearchIndex, options["--plug"])
-			
+
 				try:
 					options["--uuid"] = mappingToUUID[vm.value]
-				except KeyError, ex:
+				except KeyError:
 					fail(EC_STATUS)
-				except AttributeError, ex:
+				except AttributeError:
 					fail(EC_STATUS)
 			else:
 				## Name of virtual machine instead of path
 				## warning: if you have same names of machines this won't work correctly
 				try:
 					(options["--uuid"], _) = machines[options["--plug"]]
-				except KeyError, ex:
+				except KeyError:
 					fail(EC_STATUS)
-				except AttributeError, ex:
+				except AttributeError:
 					fail(EC_STATUS)
 
 		try:
@@ -148,24 +178,24 @@ def get_power_status(conn, options):
 				return "on"
 			else:
 				return "off"
-		except KeyError, ex:
+		except KeyError:
 			fail(EC_STATUS)
 
 def set_power_status(conn, options):
 	mo_SearchIndex = Property(options["ServiceContent"].searchIndex.value)
 	mo_SearchIndex._type = "SearchIndex"
-	vm = conn.service.FindByUuid(mo_SearchIndex, vmSearch = 1, uuid = options["--uuid"])
+	vm = conn.service.FindByUuid(mo_SearchIndex, vmSearch=1, uuid=options["--uuid"])
 
 	mo_machine = Property(vm.value)
 	mo_machine._type = "VirtualMachine"
-	
+
 	try:
 		if options["--action"] == "on":
 			conn.service.PowerOnVM_Task(mo_machine)
 		else:
 			conn.service.PowerOffVM_Task(mo_machine)
 	except suds.WebFault, ex:
-		if ((str(ex).find("Permission to perform this operation was denied")) >= 0):
+		if (str(ex).find("Permission to perform this operation was denied")) >= 0:
 			fail(EC_INVALID_PRIVILEGES)
 		else:
 			if options["--action"] == "on":
@@ -176,17 +206,26 @@ def set_power_status(conn, options):
 def remove_tmp_dir(tmp_dir):
 	shutil.rmtree(tmp_dir)
 
+def logout():
+	try:
+		conn_global.service.Logout(options_global["mo_SessionManager"])
+	except Exception:
+		pass
+
 def main():
-	device_opt = [ "ipaddr", "login", "passwd", "web", "ssl", "port" ]
+	global options_global
+	global conn_global
+	device_opt = ["ipaddr", "login", "passwd", "web", "ssl", "notls", "port"]
 
 	atexit.register(atexit_handler)
+	atexit.register(logout)
 
-	options = check_input(device_opt, process_input(device_opt))
+	options_global = check_input(device_opt, process_input(device_opt))
 
-	## 
+	##
 	## Fence agent specific defaults
 	#####
-	docs = { }
+	docs = {}
 	docs["shortdesc"] = "Fence agent for VMWare over SOAP API"
 	docs["longdesc"] = "fence_vmware_soap is an I/O Fencing agent \
 which can be used with the virtual machines managed by VMWare products \
@@ -197,23 +236,21 @@ format (e.g. /datacenter/vm/Discovered virtual machine/myMachine). \
 In the cases when name of yours VM is unique you can use it instead. \
 Alternatively you can always use UUID to access virtual machine."
 	docs["vendorurl"] = "http://www.vmware.com"
-	show_docs(options, docs)
+	show_docs(options_global, docs)
+
+	logging.basicConfig(level=logging.INFO)
+	logging.getLogger('suds.client').setLevel(logging.CRITICAL)
+	logging.getLogger("requests").setLevel(logging.CRITICAL)
+	logging.getLogger("urllib3").setLevel(logging.CRITICAL)
 
 	##
 	## Operate the fencing device
 	####
-	conn = soap_login(options)
-		
-	result = fence_action(conn, options, set_power_status, get_power_status, get_power_status)
+	conn_global = soap_login(options_global)
 
-	##
-	## Logout from system
-	#####
-	try:
-		conn.service.Logout(options["mo_SessionManager"])
-	except Exception, ex:
-		pass
+	result = fence_action(conn_global, options_global, set_power_status, get_power_status, get_power_status)
 
+	## Logout from system is done automatically via atexit()
 	sys.exit(result)
 
 if __name__ == "__main__":
diff --git a/fence/agents/wti/Makefile.am b/fence/agents/wti/Makefile.am
index 04f556c..17b6f21 100644
--- a/fence/agents/wti/Makefile.am
+++ b/fence/agents/wti/Makefile.am
@@ -10,8 +10,8 @@ sbin_SCRIPTS		= $(TARGET)
 
 man_MANS		= $(TARGET).8
 
+FENCE_TEST_ARGS         = -l test -p test -a test -n 1
+
 include $(top_srcdir)/make/fencebuild.mk
 include $(top_srcdir)/make/fenceman.mk
-
-clean-local: clean-man
-	rm -f $(TARGET)
+include $(top_srcdir)/make/agentpycheck.mk
diff --git a/fence/agents/wti/fence_wti.py b/fence/agents/wti/fence_wti.py
index c9c5237..f4ab51b 100644
--- a/fence/agents/wti/fence_wti.py
+++ b/fence/agents/wti/fence_wti.py
@@ -1,4 +1,4 @@
-#!/usr/bin/python
+#!/usr/bin/python -tt
 
 #####
 ##
@@ -11,9 +11,12 @@
 ##  WTI IPS-800-CE     v1.40h		(no username) ('list' tested)
 #####
 
-import sys, re, pexpect, exceptions
+import sys, re, pexpect
+import atexit
+import time
 sys.path.append("@FENCEAGENTSLIBDIR@")
 from fencing import *
+from fencing import fspawn, fail, fail_usage, EC_LOGIN_DENIED
 
 #BEGIN_VERSION_GENERATION
 RELEASE_VERSION="New WTI Agent - test release on steroids"
@@ -24,7 +27,7 @@ BUILD_DATE="March, 2008"
 def get_listing(conn, options, listing_command):
 	listing = ""
 
-	conn.send(listing_command + "\r\n")
+	conn.send_eol(listing_command)
 
 	if isinstance(options["--command-prompt"], list):
 		re_all = list(options["--command-prompt"])
@@ -33,11 +36,11 @@ def get_listing(conn, options, listing_command):
 	re_next = re.compile("Enter: ", re.IGNORECASE)
 	re_all.append(re_next)
 
-	result = conn.log_expect(options, re_all, int(options["--shell-timeout"]))
+	result = conn.log_expect(re_all, int(options["--shell-timeout"]))
 	listing = conn.before
 	if result == (len(re_all) - 1):
-		conn.send("\r\n")
-		conn.log_expect(options, options["--command-prompt"], int(options["--shell-timeout"]))
+		conn.send_eol("")
+		conn.log_expect(options["--command-prompt"], int(options["--shell-timeout"]))
 		listing += conn.before
 
 	return listing
@@ -51,21 +54,22 @@ def get_plug_status(conn, options):
 	status_index = -1
 	plug_header = list()
 	outlets = {}
-	
+
 	for line in listing.splitlines():
 		if (plug_section == 2) and line.find("|") >= 0 and line.startswith("PLUG") == False:
 			plug_line = [x.strip().lower() for x in line.split("|")]
 			if len(plug_line) < len(plug_header):
 				plug_section = -1
-			if ["list", "monitor"].count(options["--action"]) == 0 and options["--plug"].lower() == plug_line[plug_index]:
+			if ["list", "monitor"].count(options["--action"]) == 0 and \
+					options["--plug"].lower() == plug_line[plug_index]:
 				return plug_line[status_index]
 			else:
 				## We already believe that first column contains plug number
 				if len(plug_line[0]) != 0:
 					outlets[plug_line[0]] = (plug_line[name_index], plug_line[status_index])
-		elif (plug_section == 1):
+		elif plug_section == 1:
 			plug_section = 2
-		elif (line.upper().startswith("PLUG")):
+		elif line.upper().startswith("PLUG"):
 			plug_section = 1
 			plug_header = [x.strip().lower() for x in line.split("|")]
 			plug_index = plug_header.index("plug")
@@ -80,26 +84,31 @@ def get_plug_status(conn, options):
 def get_plug_group_status_from_list(status_list):
 	for status in status_list:
 		if status == "on":
-		      return status
+			return status
 	return "off"
 
 def get_plug_group_status(conn, options):
 	listing = get_listing(conn, options, "/SG")
 
-	plug_section = 0
 	outlets = {}
-	current_outlet = ""
 	line_index = 0
+	status_index = -1
+	plug_index = -1
+	name_index = -1
+
 	lines = listing.splitlines()
 	while line_index < len(lines) and line_index >= 0:
 		line = lines[line_index]
-		if (line.find("|") >= 0 and line.lstrip().startswith("GROUP NAME") == False):
+		if line.find("|") >= 0 and line.lstrip().startswith("GROUP NAME") == False:
 			plug_line = [x.strip().lower() for x in line.split("|")]
-			if ["list", "monitor"].count(options["--action"]) == 0 and options["--plug"].lower() == plug_line[name_index]:
+			if ["list", "monitor"].count(options["--action"]) == 0 and \
+					options["--plug"].lower() == plug_line[name_index]:
 				plug_status = []
 				while line_index < len(lines) and line_index >= 0:
 					plug_line = [x.strip().lower() for x in lines[line_index].split("|")]
-					if len(plug_line) >= max(name_index, status_index) and len(plug_line[plug_index]) > 0 and (len(plug_line[name_index]) == 0 or options["--plug"].lower() == plug_line[name_index]):
+					if len(plug_line) >= max(name_index, status_index) and \
+							len(plug_line[plug_index]) > 0 and \
+							(len(plug_line[name_index]) == 0 or options["--plug"].lower() == plug_line[name_index]):
 						## Firmware 1.43 does not have a valid value of plug on first line as only name is defined on that line
 						if not "---" in plug_line[status_index]:
 							plug_status.append(plug_line[status_index])
@@ -108,7 +117,7 @@ def get_plug_group_status(conn, options):
 						line_index = -1
 
 				return get_plug_group_status_from_list(plug_status)
- 
+
 			else:
 				## We already believe that first column contains plug number
 				if len(plug_line[0]) != 0:
@@ -128,7 +137,7 @@ def get_plug_group_status(conn, options):
 					outlets[group_name] = (group_name, get_plug_group_status_from_list(plug_status))
 				line_index += 1
 
-		elif (line.upper().lstrip().startswith("GROUP NAME")):
+		elif line.upper().lstrip().startswith("GROUP NAME"):
 			plug_header = [x.strip().lower() for x in line.split("|")]
 			name_index = plug_header.index("group name")
 			plug_index = plug_header.index("plug")
@@ -139,18 +148,23 @@ def get_plug_group_status(conn, options):
 
 
 	if ["list", "monitor"].count(options["--action"]) == 1:
-		for group, status in outlet_groups:
-			outlets[group] = (group, status[0])
+		results = {}
+		for group, status in outlets.items():
+			results[group] = (group, status[0])
 
-		return outlets
+		return results
 	else:
 		return "PROBLEM"
 
 def get_power_status(conn, options):
-	ret = get_plug_status(conn, options)
-	
-	if ret == "PROBLEM":
-		ret = get_plug_group_status(conn, options)
+	if ["list"].count(options["--action"]) == 0:
+		ret = get_plug_status(conn, options)
+
+		if ret == "PROBLEM":
+			ret = get_plug_group_status(conn, options)
+	else:
+		ret = dict(get_plug_status(conn, options).items() + \
+			get_plug_group_status(conn, options).items())
 
 	return ret
 
@@ -160,20 +174,20 @@ def set_power_status(conn, options):
 		'off': "/off"
 	}[options["--action"]]
 
-	conn.send(action + " " + options["--plug"] + ",y\r\n")
-	conn.log_expect(options, options["--command-prompt"], int(options["--power-timeout"]))
+	conn.send_eol(action + " " + options["--plug"] + ",y")
+	conn.log_expect(options["--command-prompt"], int(options["--power-timeout"]))
 
 def main():
-	device_opt = [  "ipaddr", "login", "passwd", "no_login", "no_password", \
-			"cmd_prompt", "secure", "port" ]
+	device_opt = ["ipaddr", "login", "passwd", "no_login", "no_password", \
+			"cmd_prompt", "secure", "port", "telnet"]
 
 	atexit.register(atexit_handler)
 
-	all_opt["cmd_prompt"]["default"] = [ "RSM>", "MPC>", "IPS>", "TPS>", "NBB>", "NPS>", "VMR>" ]
+	all_opt["cmd_prompt"]["default"] = ["RSM>", "MPC>", "IPS>", "TPS>", "NBB>", "NPS>", "VMR>"]
 
 	options = check_input(device_opt, process_input(device_opt))
 
-	docs = { }
+	docs = {}
 	docs["shortdesc"] = "Fence agent for WTI"
 	docs["longdesc"] = "fence_wti is an I/O Fencing agent \
 which can be used with the WTI Network Power Switch (NPS). It logs \
@@ -182,59 +196,49 @@ Lengthy telnet connections to the NPS should be avoided while a GFS cluster \
 is running because the connection will block any necessary fencing actions."
 	docs["vendorurl"] = "http://www.wti.com"
 	show_docs(options, docs)
-	
+
 	##
 	## Operate the fencing device
 	##
 	## @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:
-			try:
-				conn = fspawn(options, TELNET_PATH)
-				conn.send("set binary\n")
-				conn.send("open %s -%s\n"%(options["--ip"], options["--ipport"]))
-			except pexpect.ExceptionPexpect, ex:
-				sys.stderr.write(str(ex) + "\n")
-				sys.stderr.write("Due to limitations, binary dependencies on fence agents "
-				"are not in the spec file and must be installed separately." + "\n")
-				sys.exit(EC_GENERIC_ERROR)
-			
+			if options["--action"] in ["off", "reboot"]:
+				time.sleep(int(options["--delay"]))
+
+			options["eol"] = "\r\n"
+
+			conn = fspawn(options, options["--telnet-path"])
+			conn.send("set binary\n")
+			conn.send("open %s -%s\n"%(options["--ip"], options["--ipport"]))
+
 			re_login = re.compile("(login: )|(Login Name:  )|(username: )|(User Name :)", re.IGNORECASE)
-			re_prompt = re.compile("|".join(map (lambda x: "(" + x + ")", options["--command-prompt"])), re.IGNORECASE)
+			re_prompt = re.compile("|".join(["(" + x + ")" for x in options["--command-prompt"]]), re.IGNORECASE)
 
-			result = conn.log_expect(options, [ re_login, "Password: ", re_prompt ], int(options["--shell-timeout"]))
+			result = conn.log_expect([re_login, "Password: ", re_prompt], int(options["--shell-timeout"]))
 			if result == 0:
 				if options.has_key("--username"):
-					conn.send(options["--username"]+"\r\n")
-					result = conn.log_expect(options, [ re_login, "Password: ", re_prompt ], int(options["--shell-timeout"]))
+					conn.send_eol(options["--username"])
+					result = conn.log_expect([re_login, "Password: ", re_prompt], int(options["--shell-timeout"]))
 				else:
 					fail_usage("Failed: You have to set login name")
-		
+
 			if result == 1:
 				if options.has_key("--password"):
-					conn.send(options["--password"]+"\r\n")
-					conn.log_expect(options, options["--command-prompt"], int(options["--shell-timeout"]))	
+					conn.send_eol(options["--password"])
+					conn.log_expect(options["--command-prompt"], int(options["--shell-timeout"]))
 				else:
 					fail_usage("Failed: You have to enter password or password script")
 		except pexpect.EOF:
-			fail(EC_LOGIN_DENIED) 
+			fail(EC_LOGIN_DENIED)
 		except pexpect.TIMEOUT:
-			fail(EC_LOGIN_DENIED)		
+			fail(EC_LOGIN_DENIED)
 	else:
 		conn = fence_login(options)
 
 	result = fence_action(conn, options, set_power_status, get_power_status, get_power_status)
-
-	##
-	## Logout from system
-	######
-	try:
-		conn.send("/X"+"\r\n")
-		conn.close()
-	except:
-		pass
-		
+	fence_logout(conn, "/X")
 	sys.exit(result)
 
 if __name__ == "__main__":
diff --git a/fence/agents/xcat/Makefile.am b/fence/agents/xcat/Makefile.am
deleted file mode 100644
index ef99def..0000000
--- a/fence/agents/xcat/Makefile.am
+++ /dev/null
@@ -1,17 +0,0 @@
-MAINTAINERCLEANFILES	= Makefile.in
-
-TARGET			= fence_xcat
-
-SRC			= $(TARGET).pl
-
-EXTRA_DIST		= $(SRC)
-
-sbin_SCRIPTS		= $(TARGET)
-
-man_MANS		= $(TARGET).8
-
-include $(top_srcdir)/make/fencebuild.mk
-include $(top_srcdir)/make/fencemanperl.mk
-
-clean-local: clean-man
-	rm -f $(TARGET)
diff --git a/fence/agents/xcat/fence_xcat.pl b/fence/agents/xcat/fence_xcat.pl
deleted file mode 100644
index c2937c9..0000000
--- a/fence/agents/xcat/fence_xcat.pl
+++ /dev/null
@@ -1,250 +0,0 @@
-#!/usr/bin/perl
-
-use Getopt::Std;
-
-my $ME = $0;
-
-END {
-  defined fileno STDOUT or return;
-  close STDOUT and return;
-  warn "$ME: failed to close standard output: $!\n";
-  $? ||= 1;
-}
-
-# Get the program name from $0 and strip directory names
-$_=$0;
-s/.*\///;
-my $pname = $_;
-
-$opt_o = 'reset';        # Default fence action
-$opt_r = 'rpower';        # Default fence action
-
-# WARNING!! Do not add code bewteen "#BEGIN_VERSION_GENERATION" and 
-# "#END_VERSION_GENERATION"  It is generated by the Makefile
-
-#BEGIN_VERSION_GENERATION
-$RELEASE_VERSION="";
-$REDHAT_COPYRIGHT="";
-$BUILD_DATE="";
-#END_VERSION_GENERATION
-
-
-sub usage
-{
-    print "Usage:\n";
-    print "\n";
-    print "$pname [options]\n";
-    print "\n";
-    print "Options:\n";
-    print "  -h               usage\n";
-    print "  -n <name>        nodename\n";
-    print "  -o <string>      Action: on, off, reset (default), status or metadata\n";
-    print "  -r <rpower>      rpower command\n";
-    print "  -q               quiet mode\n";
-    print "  -V               version\n";
-
-    exit 0;
-}
-
-sub fail
-{
-  ($msg) = @_;
-  print $msg."\n" unless defined $opt_q;
-  $t->close if defined $t;
-  exit 1;
-}
-
-sub fail_usage
-{
-  ($msg)=@_;
-  print STDERR $msg."\n" if $msg;
-  print STDERR "Please use '-h' for usage.\n";
-  exit 1;
-}
-
-sub version
-{
-  print "$pname $RELEASE_VERSION $BUILD_DATE\n";
-  print "$REDHAT_COPYRIGHT\n" if ( $REDHAT_COPYRIGHT );
-
-  exit 0;
-}
-
-sub print_metadata
-{
-print '<?xml version="1.0" ?>
-<resource-agent name="fence_xcat" shortdesc="I/O Fencing agent for xcat environments" >
-<longdesc>
-fence_xcat is a wrapper to the rpower(1) command that is distributed with the xCAT project available at http://www.xcat.org. Use of fence_xcat requires that xcat has already been properly configured for your environment. Refer to xCAT(1) for more information on configuring xCAT.
-
-NOTE: It is recommended that fence_bladecenter(8) is used instead of fence_xcat if the bladecenter firmware supports telnet.  This interface is much cleaner and easier to setup.
-</longdesc>
-<vendor-url>http://www.xcat.org</vendor-url>
-<parameters>
-        <parameter name="action" unique="1" required="1">
-                <getopt mixed="-o [action]" />
-                <content type="string" default="restart" />
-                <shortdesc lang="en">Fencing Action</shortdesc>
-        </parameter>
-        <parameter name="nodename" unique="1" required="1">
-                <getopt mixed="-n [nodename]" />
-                <content type="string"  />
-                <shortdesc lang="en">The nodename as defined in nodelist.tab of the xCAT setup.</shortdesc>
-        </parameter>
-        <parameter name="rpower" unique="1" required="0">
-                <getopt mixed="-r [rpower]" />
-                <content type="string"  />
-                <shortdesc lang="en">The path to the rpower binary.</shortdesc>
-        </parameter>
-        <parameter name="help" unique="1" required="0">
-                <getopt mixed="-h" />           
-                <content type="string"  />
-                <shortdesc lang="en">Display help and exit</shortdesc>                    
-        </parameter>
-</parameters>
-<actions>
-        <action name="on" />
-        <action name="off" />
-        <action name="status" />
-        <action name="metadata" />
-</actions>
-</resource-agent>
-';
-}
-
-
-sub get_options_stdin
-{
-    my $opt;
-    my $line = 0;
-    while( defined($in = <>) )
-    {
-        $_ = $in;
-        chomp;
-
-	# strip leading and trailing whitespace
-        s/^\s*//;
-        s/\s*$//;
-
-	# skip comments
-        next if /^#/;
-
-        $line+=1;
-        $opt=$_;
-        next unless $opt;
-
-        ($name,$val)=split /\s*=\s*/, $opt;
-
-        if ( $name eq "" )
-        {  
-           print STDERR "parse error: illegal name in option $line\n";
-           exit 2;
-	}
-	
-        # DO NOTHING -- this field is used by fenced
-	elsif ($name eq "agent" ) { } 
-
-        elsif ($name eq "action" )
-        {
-            $opt_o = $val;
-        }
-	elsif ($name eq "nodename" ) 
-	{
-            $opt_n = $val;
-        } 
-	elsif ($name eq "rpower" ) 
-	{
-            $opt_r = $val;
-        } 
-
-    }
-}
-
-######################################################################33
-# MAIN
-
-if (@ARGV > 0) {
-   getopts("hn:o:r:qV") || fail_usage ;
-
-   usage if defined $opt_h;
-   version if defined $opt_V;
-
-   fail_usage "Unknown parameter." if (@ARGV > 0);
-
-   if ((defined $opt_o) && ($opt_o =~ /metadata/i)) {
-     print_metadata();
-     exit 0;
-   }
-
-   fail_usage "No '-n' flag specified." unless defined $opt_n;
-   $opt_o=lc($opt_o);
-   fail_usage "Unrecognised action '$opt_o' for '-o' flag"
-      unless $opt_o =~ /^(on|off|reset|stat|status)$/;
-
-} else {
-   get_options_stdin();
-
-   if ((defined $opt_o) && ($opt_o =~ /metadata/i)) {
-     print_metadata();
-     exit 0;
-   }
-   
-   fail "failed: no plug number" unless defined $opt_n;
-   $opt_o=lc($opt_o);
-   fail "failed: unrecognised action: $opt_o"
-      unless $opt_o =~ /^(on|off|reset|stat|status)$/;
-}
-
-pipe (RDR,WTR);
-
-if ( $pid=fork() == 0 )
-{
-   close RDR;
-
-   open STDOUT, ">&WTR";
-   exec "$opt_r $opt_n $opt_o" or die "failed to exec \"$opt_r\"\n";
-}
-
-close WTR;
-
-wait;
-
-if ( $? != 0 )
-{
-   die "failed: rpower error: exit $?\n"
-}
-
-$found=0;
-$status="";
-while (<RDR>)
-{
-   chomp;
-
-   if ( $_ =~ /^(\S+): (\S+)$/)
-   {
-      if ($opt_n eq $1) 
-      {
-         $status = $2;
-
-         if (($opt_o eq $2) || ($opt_o =~ /stat/i) || ($opt_o =~ /status/i))
-         {
-            $found=1;
-            last;
-         }
-      }
-   }
-}
-
-print (($found ? "success":"failed") . ": $opt_n $status\n")
-   unless defined $opt_q;
-
-exit ($found ? 0 : 1 );
-
-
-
-
-
-
-
-
-
diff --git a/fence/agents/xenapi/Makefile.am b/fence/agents/xenapi/Makefile.am
index 781975e..1f05023 100644
--- a/fence/agents/xenapi/Makefile.am
+++ b/fence/agents/xenapi/Makefile.am
@@ -10,8 +10,8 @@ sbin_SCRIPTS		= $(TARGET)
 
 man_MANS		= $(TARGET).8
 
+FENCE_TEST_ARGS         = -l test -p test -n 1 --session-url http://test
+
 include $(top_srcdir)/make/fencebuild.mk
 include $(top_srcdir)/make/fenceman.mk
-
-clean-local: clean-man
-	rm -f $(TARGET)
+include $(top_srcdir)/make/agentpycheck.mk
diff --git a/fence/agents/xenapi/fence_xenapi.py b/fence/agents/xenapi/fence_xenapi.py
index 9cf200a..5fe7646 100644
--- a/fence/agents/xenapi/fence_xenapi.py
+++ b/fence/agents/xenapi/fence_xenapi.py
@@ -1,4 +1,4 @@
-#!/usr/bin/python
+#!/usr/bin/python -tt
 #
 #############################################################################
 # Copyright 2011 Matthew Clark
@@ -8,12 +8,12 @@
 # it under the terms of the GNU General Public License as published by
 # the Free Software Foundation, either version 2 of the License, or
 # (at your option) any later version.
-# 
+#
 # fence-xenserver is distributed in the hope that it will be useful,
 # but WITHOUT ANY WARRANTY; without even the implied warranty of
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 # GNU General Public License for more details.
-# 
+#
 # You should have received a copy of the GNU General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
@@ -32,8 +32,10 @@
 # whether I should continue support for it. mattjclark0407 at hotmail dot com
 
 import sys
+import atexit
 sys.path.append("@FENCEAGENTSLIBDIR@")
 from fencing import *
+from fencing import run_delay
 import XenAPI
 
 #BEGIN_VERSION_GENERATION
@@ -42,14 +44,14 @@ REDHAT_COPYRIGHT=""
 BUILD_DATE=""
 #END_VERSION_GENERATION
 
-EC_BAD_SESSION 		= 1
+EC_BAD_SESSION = 1
 # Find the status of the port given in the -U flag of options.
 def get_power_fn(session, options):
 	if options.has_key("--verbose"):
 		verbose = True
 	else:
 		verbose = False
-		
+
 	try:
 		# Get a reference to the vm specified in the UUID or vm_name/port parameter
 		vm = return_vm_reference(session, options)
@@ -57,7 +59,7 @@ def get_power_fn(session, options):
 		record = session.xenapi.VM.get_record(vm)
 		# 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 not record["is_a_template"] and not record["is_control_domain"]:
 			status = record["power_state"]
 			if verbose:
 				print "UUID:", record["uuid"], "NAME:", record["name_label"], "POWER STATUS:", record["power_state"]
@@ -69,7 +71,7 @@ def get_power_fn(session, options):
 			# We want to make sure that we only return the status "off" if the machine is actually halted as the status
 			# is checked before a fencing action. Only when the machine is Halted is it not consuming resources which
 			# may include whatever you are trying to protect with this fencing action.
-			return (status=="Halted" and "off" or "on")
+			return status == "Halted" and "off" or "on"
 	except Exception, exn:
 		print str(exn)
 
@@ -77,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)
@@ -86,14 +86,14 @@ def set_power_fn(session, options):
 		record = session.xenapi.VM.get_record(vm)
 		# 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" ):
-				# Start the VM 
+		if not record["is_a_template"] and not record["is_control_domain"]:
+			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:
@@ -115,7 +115,7 @@ def get_outlet_list(session, options):
 			record = session.xenapi.VM.get_record(vm)
 			# 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 not record["is_a_template"] and not record["is_control_domain"]:
 				name = record["name_label"]
 				uuid = record["uuid"]
 				status = record["power_state"]
@@ -141,11 +141,11 @@ def connect_and_login(options):
 	except Exception, exn:
 		print str(exn)
 		# http://sources.redhat.com/cluster/wiki/FenceAgentAPI says that for no connectivity
-		# the exit value should be 1. It doesn't say anything about failed logins, so 
+		# the exit value should be 1. It doesn't say anything about failed logins, so
 		# until I hear otherwise it is best to keep this exit the same to make sure that
 		# anything calling this script (that uses the same information in the web page
 		# above) knows that this is an error condition, not a msg signifying a down port.
-		sys.exit(EC_BAD_SESSION) 
+		sys.exit(EC_BAD_SESSION)
 	return session
 
 # return a reference to the VM by either using the UUID or the vm_name/port. If the UUID is set then
@@ -165,11 +165,10 @@ def return_vm_reference(session, options):
 		# need to catch and re-raise the exception produced by get_by_uuid.
 		try:
 			return session.xenapi.VM.get_by_uuid(uuid)
-		except Exception, exn:
+		except Exception:
 			if verbose:
 				print "No VM's found with a UUID of \"%s\"" % uuid
 			raise
-		
 
 	# Case where the vm_name/port has been specified
 	if options.has_key("--plug"):
@@ -200,27 +199,27 @@ def return_vm_reference(session, options):
 
 def main():
 
-	device_opt = [	"login", "passwd", "port", "no_login", "no_password", "session_url" ]
+	device_opt = ["login", "passwd", "port", "no_login", "no_password", "session_url", "web"]
 
 	atexit.register(atexit_handler)
 
 	options = check_input(device_opt, process_input(device_opt))
 
-	docs = { }
-	docs["shortdesc"] = "XenAPI based fencing for the Citrix XenServer virtual machines."
+	docs = {}
+	docs["shortdesc"] = "Fence agent for Citrix XenServer over XenAPI"
 	docs["longdesc"] = "\
 fence_cxs is an I/O Fencing agent used on Citrix XenServer hosts. \
 It uses the XenAPI, supplied by Citrix, to establish an XML-RPC sesssion \
 to a XenServer host. Once the session is established, further XML-RPC \
 commands are issued in order to switch on, switch off, restart and query \
-the status of virtual machines running on the host." 
+the status of virtual machines running on the host."
 	docs["vendorurl"] = "http://www.xenproject.org"
 	show_docs(options, docs)
 
-	xenSession = connect_and_login(options)
-	
-	# Operate the fencing device
-	result = fence_action(xenSession, options, set_power_fn, get_power_fn, get_outlet_list)
+	run_delay(options)
+
+	xen_session = connect_and_login(options)
+	result = fence_action(xen_session, options, set_power_fn, get_power_fn, get_outlet_list)
 
 	sys.exit(result)
 
diff --git a/fence/agents/zvm/Makefile.am b/fence/agents/zvm/Makefile.am
index 2dc0005..a29754d 100644
--- a/fence/agents/zvm/Makefile.am
+++ b/fence/agents/zvm/Makefile.am
@@ -1,13 +1,17 @@
 MAINTAINERCLEANFILES	= Makefile.in
 
-sbin_PROGRAMS		= fence_zvm fence_zvmip
+TARGET			= fence_zvmip
 
-noinst_HEADERS		= fence_zvm.h
+SRC			= $(TARGET).py
 
-fence_zvm_SOURCES	= fence_zvm.c
-fence_zvm_CFLAGS	= -D_GNU_SOURCE
+EXTRA_DIST		= $(SRC)
 
-fence_zvmip_SOURCES	= fence_zvmip.c
-fence_zvmip_CFLAGS	= -D_GNU_SOURCE
+sbin_SCRIPTS		= $(TARGET)
 
-dist_man_MANS		= fence_zvm.8 fence_zvmip.8
+man_MANS		= $(TARGET).8
+
+FENCE_TEST_ARGS         = -l test -p test -a test -n 1
+
+include $(top_srcdir)/make/fencebuild.mk
+include $(top_srcdir)/make/fenceman.mk
+include $(top_srcdir)/make/agentpycheck.mk
diff --git a/fence/agents/zvm/fence_zvm.8 b/fence/agents/zvm/fence_zvm.8
deleted file mode 100644
index 46bfe3f..0000000
--- a/fence/agents/zvm/fence_zvm.8
+++ /dev/null
@@ -1,81 +0,0 @@
-.TH fence_zvm 8
-
-.SH NAME
-fence_zvm - Power Fencing agent for GFS on System z z/VM Clusters
-
-.SH SYNOPSIS
-.B
-fence_zvm
-[\fIOPTION\fR]...
-
-.SH DESCRIPTION
-fence_zvm is a Power Fencing agent used on a GFS virtual machine in a System z z/VM cluster.
-It uses the SMAPI interface to recycle an active image.
-
-fence_zvm accepts options on the command line as well as from stdin.
-fence_node sends the options through stdin when it execs the agent.
-fence_zvm can be run by itself with command line options which is useful
-for testing.
-
-Vendor URL: http://www.sinenomine.net
-
-.SH OPTIONS
-.TP
-\fB-o --action\fP
-Fencing action: "off" - fence off device; "metadata" - display device metadata
-.TP
-\fB-n --plug\fP \fItarget\fP
-Name of virtual machine to recycle.
-.TP
-\fB-h --help\fP
-Print out a help message describing available options, then exit.
-.TP
-\fB-a --ip\fP \fIsmapi Server\fP
-\fBName\fP of SMAPI server virtual machine. To be consistent with other fence agents thisname is a little misleading: it is the name of the virtual machine not its IP address or hostname.
-.TP
-\fB-h --help\fP
-Display usage information
-.TP
-\fI-t --timeout = < shutdown timeout >\fP
-Amount of \fIgrace\fP time to give the virtual machine to shutdown cleanly before being
-forcibly terminated. Currently, this option is ignored.
-
-.SH STDIN PARAMETERS
-.TP
-\fIagent = < param >\fP
-This option is used by fence_node(8) and is ignored by fence_zvm.
-.TP
-\fIaction = < action >\fP
-Fencing action: "off" - fence off device; "metadata" - display device metadata
-.TP
-\fIport = < target >\fP
-Name of virtual machine to recycle.
-.TP
-\fIipaddr= < server name >\fP
-\fBName\fP of SMAPI server virtual machine. To be consistent with other fence agents thisname is a little misleading: it is the name of the virtual machine not its IP address or hostname.
-.TP
-\fItimeout = < shutdown timeout >\fP
-Amount of \fIgrace\fP time to give the virtual machine to shutdown cleanly before being
-forcibly terminated. Currently, this option is ignored.
-
-.SH SEE ALSO
-fence(8), fenced(8), fence_node(8)
-
-.SH NOTES
-To use this agent the z/VM SMAPI service needs to be configured to allow the virtual
-machine running this agent to connect to it and issue the image_recycle operation.
-This involves updating the VSMWORK1 AUTHLIST VMSYS:VSMWORK1. file. The entry should look
-something similar to this:
-
-.nf
-Column 1                   Column 66                Column 131
-|                          |                        |
-V                          V                        V
-XXXXXXXX                   ALL                      IMAGE_OPERATIONS
-.fi
-
-Where XXXXXXX is the name of the virtual machine where the agent resides. 
-
-In addition, the VM directory entry that defines this virtual machine requires the
-IUCV ANY statement (or IUCV <userid of SMAPI Server>). This authorizes use of IUCV
-to connect to the SMAPI server.
diff --git a/fence/agents/zvm/fence_zvm.c b/fence/agents/zvm/fence_zvm.c
index e553b85..2f82e25 100644
--- a/fence/agents/zvm/fence_zvm.c
+++ b/fence/agents/zvm/fence_zvm.c
@@ -49,19 +49,31 @@
 
 #define MIN(a,b)	((a) < (b) ? (a) : (b))
 #define DEFAULT_TIMEOUT 300
+#define DEFAULT_DELAY   0
+
+#define ACT_OFFON 	0
+#define ACT_OFF		1
+#define ACT_ON		2
+#define ACT_METADATA	3
+#define ACT_STATUS	4
+#define ACT_MONITOR	5
+#define ACT_LIST	6
+#define ACT_HELP	7
 
 static int zvm_smapi_reportError(void *, void *);
 
 static struct option longopts[] = {
 	{"action",	required_argument,	NULL, 'o'},
+	{"delay",	required_argument,	NULL, 'h'},
 	{"help",	no_argument,		NULL, 'h'},
 	{"ip",		required_argument,	NULL, 'a'},
 	{"plug",	required_argument,	NULL, 'n'},
 	{"timeout",	required_argument,	NULL, 'T'},
+	{"zvmsys",   	required_argument,	NULL, 'z'},
 	{NULL,		0,			NULL, 0}
 };
 
-static char *optString = "a:ho:n:T:";
+static const char *optString = "a:ho:n:T:";
 
 static int zvm_metadata(void);
 static int usage(void);
@@ -93,6 +105,7 @@ zvm_smapi_open(zvm_driver_t *zvm)
 		if ((rc = bind(zvm->sd,siucv_ptr,sockaddrlen)) != -1) {
 			memcpy(&siucv_addr.siucv_user_id,zvm->smapiSrv,strlen(zvm->smapiSrv));
 			memcpy(&siucv_addr.siucv_name,&iucvprog,8);
+			memcpy(&siucv_addr.siucv_nodeid,zvm->node,strlen(zvm->node));
 			rc = connect(zvm->sd,(__CONST_SOCKADDR_ARG)siucv_ptr,sockaddrlen);
 		}
 		if (rc == -1) {
@@ -134,6 +147,12 @@ zvm_smapi_imageRecycle(zvm_driver_t *zvm)
 	uint32_t reqId;
 	int	rc;
 
+	/*
+	 * Implement any delay
+	 */ 
+	if (zvm->delay > 0) 
+		sleep(zvm->delay);
+
 	lInPlist = sizeof(*inPlist) + strlen(zvm->target);
 	inPlist = malloc(lInPlist);
 	if (inPlist != NULL) {
@@ -175,6 +194,239 @@ zvm_smapi_imageRecycle(zvm_driver_t *zvm)
 }
 
 /**
+ * zvm_smapi_imageDeactivate
+ * @zvm: z/VM driver information
+ *
+ * Deactivates a virtual image
+ */
+int
+zvm_smapi_imageDeactivate(zvm_driver_t *zvm)
+{
+	struct _inPlist {
+		int32_t	lPlist;
+		int32_t	lFName;
+		char	fName[16];
+		int32_t lUser;
+		int32_t lPass;
+		int32_t	lTarget;
+		char	target[0];
+	} __attribute__ ((__packed__)) *inPlist;
+	struct _deactTime {
+		int32_t lForceTime;
+		char	forceTime[5];
+	} __attribute__ ((__packed__)) *deactTime;
+	int32_t	lInPlist;
+	struct	_outPlist {
+		smapiOutHeader_t hdr;
+		int32_t	nActive;
+		int32_t	nInActive;
+		int32_t	lFail;
+		char	failArray[0];
+	} *outPlist = NULL;
+	void	*pOut = NULL;
+	int32_t	lRsp;
+	uint32_t reqId;
+	int	rc;
+
+	/*
+	 * Implement any delay
+	 */ 
+	if (zvm->delay > 0) 
+		sleep(zvm->delay);
+
+	lInPlist = sizeof(*inPlist) + strlen(zvm->target) + sizeof(*deactTime);
+	inPlist = malloc(lInPlist);
+	if (inPlist != NULL) {
+		inPlist->lPlist = lInPlist - sizeof(inPlist->lPlist);
+		inPlist->lFName = sizeof(inPlist->fName);
+		memcpy(inPlist->fName, Image_Deactivate, sizeof(inPlist->fName));
+		deactTime = (void *) ((intptr_t) inPlist + sizeof(*inPlist) + strlen(zvm->target));
+		deactTime->lForceTime = sizeof(deactTime->forceTime);
+		memcpy(deactTime->forceTime, "IMMED", sizeof(deactTime->forceTime));
+		inPlist->lUser = inPlist->lPass = 0;
+		inPlist->lTarget = strlen(zvm->target);
+		memcpy(inPlist->target, zvm->target, inPlist->lTarget);
+		if ((rc = zvm_smapi_send(zvm, inPlist, &reqId, lInPlist)) != -1) {
+			if ((rc = zvm_smapi_recv(zvm, &pOut, &lRsp)) != -1) {
+				outPlist = pOut;
+				if (outPlist->hdr.rc == 0) {
+					syslog(LOG_INFO, "Deactivation of %s successful",
+					       zvm->target);
+					rc = 0;
+				} else {
+					if ((outPlist->hdr.rc == RCERR_IMAGEOP) &
+					    ((outPlist->hdr.reason == RS_NOT_ACTIVE) |
+					     (outPlist->hdr.reason == RS_BEING_DEACT))) {
+						syslog(LOG_INFO, "Deactivation of %s successful",
+						       zvm->target);
+						rc = 0;
+					} else {
+						rc = outPlist->hdr.rc;
+						zvm->reason = outPlist->hdr.reason;
+						(void) zvm_smapi_reportError(inPlist, outPlist);
+					}
+				}
+			}
+		}
+		free(inPlist);
+		free(outPlist);
+	} else {
+		syslog(LOG_ERR, "%s - cannot allocate parameter list", __func__);
+		rc = -1;
+	}
+	return(rc);
+}
+
+/**
+ * zvm_smapi_imageActivate
+ * @zvm: z/VM driver information
+ *
+ * Deactivates a virtual image
+ */
+int
+zvm_smapi_imageActivate(zvm_driver_t *zvm)
+{
+	struct _inPlist {
+		int32_t	lPlist;
+		int32_t	lFName;
+		char	fName[14];
+		int32_t lUser;
+		int32_t lPass;
+		int32_t	lTarget;
+		char	target[0];
+	} __attribute__ ((__packed__)) *inPlist;
+	int32_t	lInPlist;
+	struct	_outPlist {
+		smapiOutHeader_t hdr;
+		int32_t	nActive;
+		int32_t	nInActive;
+		int32_t	lFail;
+		char	failArray[0];
+	} *outPlist = NULL;
+	void	*pOut = NULL;
+	int32_t	lRsp;
+	uint32_t reqId;
+	int	rc;
+
+	/*
+	 * Implement any delay
+	 */ 
+	if (zvm->delay > 0) 
+		sleep(zvm->delay);
+
+	lInPlist = sizeof(*inPlist) + strlen(zvm->target);
+	inPlist = malloc(lInPlist);
+	if (inPlist != NULL) {
+		inPlist->lPlist = lInPlist - sizeof(inPlist->lPlist);
+		inPlist->lFName = sizeof(inPlist->fName);
+		memcpy(inPlist->fName, Image_Activate, sizeof(inPlist->fName));
+		inPlist->lUser = inPlist->lPass = 0;
+		inPlist->lTarget = strlen(zvm->target);
+		memcpy(inPlist->target, zvm->target, inPlist->lTarget);
+		if ((rc = zvm_smapi_send(zvm, inPlist, &reqId, lInPlist)) != -1) {
+			if ((rc = zvm_smapi_recv(zvm, &pOut, &lRsp)) != -1) {
+				outPlist = pOut;
+				if (outPlist->hdr.rc == 0) {
+					syslog(LOG_INFO, "Activation of %s successful",
+					       zvm->target);
+					rc = 0;
+				} else {
+					if ((outPlist->hdr.rc == RCERR_IMAGEOP) &
+					     (outPlist->hdr.reason == RS_ALREADY_ACTIVE)) {
+						syslog(LOG_INFO, "Activation of %s successful",
+						       zvm->target);
+						rc = 0;
+					} else {
+						rc = outPlist->hdr.rc;
+						zvm->reason = outPlist->hdr.reason;
+						(void) zvm_smapi_reportError(inPlist, outPlist);
+					}
+				}
+			}
+		}
+		free(inPlist);
+		free(outPlist);
+	} else {
+		syslog(LOG_ERR, "%s - cannot allocate parameter list", __func__);
+		rc = -1;
+	}
+	return(rc);
+}
+
+/**
+ * zvm_smapi_imageQuery
+ * @zvm: z/VM driver information
+ *
+ * Queries the state of a virtual image
+ */
+int
+zvm_smapi_imageQuery(zvm_driver_t *zvm)
+{
+	struct _inPlist {
+		int32_t	lPlist;
+		int32_t	lFName;
+		char	fName[18];
+		int32_t lUser;
+		int32_t lPass;
+		int32_t	lTarget;
+		char	target[0];
+	} __attribute__ ((__packed__)) *inPlist;
+	int32_t	lInPlist;
+	struct	_outPlist {
+		smapiOutHeader_t hdr;
+		int32_t	lNames;
+		char	nameArray[0];
+	} *outPlist = NULL;
+	void	*pOut = NULL;
+	int32_t	lRsp;
+	uint32_t reqId;
+	int	rc;
+
+	/*
+	 * Implement any delay
+	 */ 
+	if (zvm->delay > 0) 
+		sleep(zvm->delay);
+
+	lInPlist = sizeof(*inPlist) + strlen(zvm->target);
+	inPlist = malloc(lInPlist);
+	if (inPlist != NULL) {
+		inPlist->lPlist = lInPlist - sizeof(inPlist->lPlist);
+		inPlist->lFName = sizeof(inPlist->fName);
+		memcpy(inPlist->fName, Image_Status_Query, sizeof(inPlist->fName));
+		inPlist->lUser = inPlist->lPass = 0;
+		inPlist->lTarget = strlen(zvm->target);
+		memcpy(inPlist->target, zvm->target, inPlist->lTarget);
+		if ((rc = zvm_smapi_send(zvm, inPlist, &reqId, lInPlist)) != -1) {
+			if ((rc = zvm_smapi_recv(zvm, &pOut, &lRsp)) != -1) {
+				outPlist = pOut;
+				if (outPlist->hdr.rc == 0) {
+					if (outPlist->hdr.reason == 0) {
+						syslog(LOG_INFO, "Node %s is active",
+						       zvm->target);
+						rc = 0;
+					} else { 
+						syslog(LOG_INFO, "Node %s is inactive",
+						       zvm->target);
+						rc = 2;
+					}
+				} else {
+					rc = 1;
+					zvm->reason = outPlist->hdr.reason;
+					(void) zvm_smapi_reportError(inPlist, outPlist);
+				}
+			}
+		}
+		free(inPlist);
+		free(outPlist);
+	} else {
+		syslog(LOG_ERR, "%s - cannot allocate parameter list", __func__);
+		rc = -1;
+	}
+	return(rc);
+}
+
+/**
  * zvm_smapi_send:
  * @zvm: z/VM driver information
  * @reqid: Returned request id
@@ -355,6 +607,7 @@ zvm_metadata()
 	fprintf (stdout, "<longdesc>");
 	fprintf (stdout, "The fence_zvm agent is intended to be used with with z/VM SMAPI service.");
 	fprintf (stdout, "</longdesc>\n");
+	fprintf (stdout, "<vendor-url>http://www.ibm.com</vendor-url>\n");
 
 	fprintf (stdout, "<parameters>\n");
 
@@ -372,6 +625,13 @@ zvm_metadata()
 	     "Name of the SMAPI IUCV Server Virtual Machine");
 	fprintf (stdout, "\t</parameter>\n");
 
+	fprintf (stdout, "\t<parameter name=\"zvmsys\" unique=\"1\" required=\"0\">\n");
+	fprintf (stdout, "\t\t<getopt mixed=\"--zvmsys\" />\n");
+	fprintf (stdout, "\t\t<content type=\"string\" />\n");
+	fprintf (stdout, "\t\t<shortdesc lang=\"en\">%s</shortdesc>\n",
+	     "Node of the SMAPI IUCV Server Virtual Machine");
+	fprintf (stdout, "\t</parameter>\n");
+
 	fprintf (stdout, "\t<parameter name=\"action\" unique=\"1\" required=\"0\">\n");
 	fprintf (stdout, "\t\t<getopt mixed=\"-o, --action\" />\n");
 	fprintf (stdout, "\t\t<content type=\"string\" default=\"off\" />\n");
@@ -379,6 +639,13 @@ zvm_metadata()
 	     "Fencing action");
 	fprintf (stdout, "\t</parameter>\n");
 
+	fprintf (stdout, "\t<parameter name=\"delay\" unique=\"1\" required=\"0\">\n");
+	fprintf (stdout, "\t\t<getopt mixed=\"--delay\" />\n");
+	fprintf (stdout, "\t\t<content type=\"string\" default=\"0\" />\n");
+	fprintf (stdout, "\t\t<shortdesc lang=\"en\">%s</shortdesc>\n",
+	     "Time to delay fencing action in seconds");
+	fprintf (stdout, "\t</parameter>\n");
+
 	fprintf (stdout, "\t<parameter name=\"usage\" unique=\"1\" required=\"0\">\n");
 	fprintf (stdout, "\t\t<getopt mixed=\"-h, --help\" />\n");
 	fprintf (stdout, "\t\t<content type=\"boolean\" />\n");
@@ -390,7 +657,12 @@ zvm_metadata()
 
 	fprintf (stdout, "<actions>\n");
 	fprintf (stdout, "\t<action name=\"off\" />\n");
+	fprintf (stdout, "\t<action name=\"on\" automatic=\"0\" />\n");
+	fprintf (stdout, "\t<action name=\"list\" />\n");
 	fprintf (stdout, "\t<action name=\"metadata\" />\n");
+	fprintf (stdout, "\t<action name=\"monitor\" />\n");
+	fprintf (stdout, "\t<action name=\"reboot\" />\n");
+	fprintf (stdout, "\t<action name=\"status\" />\n");
 	fprintf (stdout, "</actions>\n");
 
 	fprintf (stdout, "</resource-agent>\n");
@@ -412,8 +684,9 @@ get_options_stdin (zvm_driver_t *zvm)
 		*opt,
 		*arg;
 	int32_t lSrvName,
+		lSrvNode,
 		lTarget;
-	int	fence = 0;
+	int	fence = ACT_OFFON;
 
 	while (fgets (buf, sizeof (buf), stdin) != 0) {
 		if (trim(buf) == 0) {
@@ -436,12 +709,22 @@ get_options_stdin (zvm_driver_t *zvm)
 			continue;
 
 		if (!strcasecmp (opt, "action")) {
-			if (strcasecmp(arg, "off") == 0) {
-				fence = 0;
+			if (strcasecmp(arg, "reboot") == 0) {
+				fence = ACT_OFFON;
+			} else if (strcasecmp(arg, "off") == 0) {
+				fence = ACT_OFF;
+			} else if (strcasecmp(arg, "on") == 0) {
+				fence = ACT_ON;
 			} else if (strcasecmp(arg, "metadata") == 0) {
-				fence = 1;
+				fence = ACT_METADATA;
+			} else if (strcasecmp(arg, "status") == 0) {
+				fence = ACT_STATUS;
+			} else if (strcasecmp(arg, "monitor") == 0) {
+				fence = ACT_MONITOR;
+			} else if (strcasecmp(arg, "list") == 0) {
+				fence = ACT_LIST;
 			} else {
-				fence = 2;
+				fence = ACT_HELP;
 			}
 		} else if (!strcasecmp (opt, "ipaddr")) {
 			lSrvName = MIN(strlen(arg), sizeof(zvm->smapiSrv));
@@ -456,11 +739,23 @@ get_options_stdin (zvm_driver_t *zvm)
 			if (*endPtr != 0) {
 				syslog(LOG_WARNING, "Invalid timeout value specified %s "
 				       "defaulting to %d", 
-				       arg, DEFAULT_TIMEOUT);
-				zvm->timeOut = DEFAULT_TIMEOUT;
+				       arg, DEFAULT_DELAY);
+				zvm->timeOut = DEFAULT_DELAY;
+			}
+		} else if (!strcasecmp (opt, "zvmsys")) {
+			lSrvNode = MIN(strlen(arg), sizeof(zvm->node));
+			memcpy(zvm->node, arg, lSrvNode);
+			continue;
+		} else if (!strcasecmp (opt, "delay")) {
+			zvm->delay = strtoul(arg, &endPtr, 10);
+			if (*endPtr != 0) {
+				syslog(LOG_WARNING, "Invalid delay value specified %s "
+				       "defaulting to %d", 
+				       arg, DEFAULT_DELAY);
+				zvm->delay = DEFAULT_DELAY;
 			}
 		} else if (!strcasecmp (opt, "help")) {
-			fence = 2;
+			fence = ACT_HELP;
 		}
 	}
 	return(fence);
@@ -477,8 +772,9 @@ static int
 get_options(int argc, char **argv, zvm_driver_t *zvm)
 {
 	int	c,
-		fence = 0;
+		fence = ACT_OFFON;
 	int32_t	lSrvName,
+		lSrvNode,
 		lTarget;
 	char	*endPtr;
 
@@ -489,19 +785,29 @@ get_options(int argc, char **argv, zvm_driver_t *zvm)
 			memcpy(zvm->target, optarg, lTarget);
 			break;
 		case 'o' :
-			if (strcasecmp(optarg, "off") == 0) {
-				fence = 0;
+			if (strcasecmp(optarg, "reboot") == 0) {
+				fence = ACT_OFFON;
+			} else if (strcasecmp(optarg, "off") == 0) {
+				fence = ACT_OFF;
+			} else if (strcasecmp(optarg, "on") == 0) {
+				fence = ACT_ON;
 			} else if (strcasecmp(optarg, "metadata") == 0) {
-				fence = 1;
+				fence = ACT_METADATA;
+			} else if (strcasecmp(optarg, "status") == 0) {
+				fence = ACT_STATUS;
+			} else if (strcasecmp(optarg, "monitor") == 0) {
+				fence = ACT_MONITOR;
+			} else if (strcasecmp(optarg, "list") == 0) {
+				fence = ACT_LIST;
 			} else {
-				fence = 2;
+				fence = ACT_HELP;
 			}
 			break;
-		case 's' :
+		case 'a' :
 			lSrvName = MIN(strlen(optarg), sizeof(zvm->smapiSrv));
 			memcpy(zvm->smapiSrv, optarg, lSrvName);
 			break;
-		case 't' :
+		case 'T' :
 			zvm->timeOut = strtoul(optarg, &endPtr, 10);
 			if (*endPtr != 0) {
 				syslog(LOG_WARNING, "Invalid timeout value specified: %s - "
@@ -510,8 +816,21 @@ get_options(int argc, char **argv, zvm_driver_t *zvm)
 				zvm->timeOut = DEFAULT_TIMEOUT;
 			}
 			break;
+		case 'd' :
+			zvm->delay = strtoul(optarg, &endPtr, 10);
+			if (*endPtr != 0) {
+				syslog(LOG_WARNING, "Invalid delay value specified: %s - "
+				       "defaulting to %d", 
+				       optarg, DEFAULT_DELAY);
+				zvm->delay = DEFAULT_DELAY;
+			}
+			break;
+		case 'z' :
+			lSrvNode = MIN(strlen(optarg), sizeof(zvm->node));
+			memcpy(zvm->node, optarg, lSrvNode);
+			break;
 		default :
-			fence = 2;
+			fence = ACT_HELP;
 		}
 	}
 	return(fence);
@@ -526,11 +845,14 @@ usage()
 {
 	fprintf(stderr,"Usage: fence_zvm [options]\n\n"
 		"\tWhere [options] =\n"
-		"\t-o --action [action]    - \"off\", \"metadata\"\n"
-		"\t-n --plug [target]      - Name of virtual machine to fence\n"
-		"\t-s --server [server]    - Name of SMAPI IUCV Request server\n"
-		"\t-T --timeout [secs]     - Time to wait for fence in seconds - currently ignored\n"
-		"\t-h --help               - Display this usage information\n");
+		"\t-o --action [action] - \"off\", \"on\", \"list\", \"metadata\", "
+					 "\"monitor\", \"reboot\", \"status\"\n"
+		"\t--delay [seconds]    - Time to delay fencing action in seconds\n"
+		"\t-n --plug [target]   - Name of virtual machine to fence\n"
+		"\t-a --ip [server]     - Name of SMAPI IUCV Request server\n"
+		"\t-T --timeout [secs]  - Time to wait for fence in seconds - currently ignored\n"
+		"\t--zvmsys [node]      - z/VM Node on which SMAPI server lives\n"
+		"\t-h --help            - Display this usage information\n");
 	return(1);
 }
 
@@ -568,6 +890,7 @@ main(int argc, char **argv)
 	openlog ("fence_zvm", LOG_CONS|LOG_PID, LOG_DAEMON);
 	memset(&zvm, 0, sizeof(zvm));
 	zvm.timeOut = DEFAULT_TIMEOUT;
+	zvm.delay   = DEFAULT_DELAY;
 
 	if (argc > 1)
 		fence = get_options(argc, argv, &zvm);
@@ -575,14 +898,33 @@ main(int argc, char **argv)
 		fence = get_options_stdin(&zvm);
 
 	switch(fence) {
-		case 0 :
-			if ((rc = check_parm(&zvm)) == 0)
+		case ACT_OFFON :	// OFFON
+			if ((rc = check_parm(&zvm)) == 0) 
 				rc = zvm_smapi_imageRecycle(&zvm);
 			break;
-		case 1 :
+		case ACT_OFF :		// OFF
+			if ((rc = check_parm(&zvm)) == 0)
+				rc = zvm_smapi_imageDeactivate(&zvm);
+			break;
+		case ACT_ON :		// ON
+			if ((rc = check_parm(&zvm)) == 0)
+				rc = zvm_smapi_imageActivate(&zvm);
+			break;
+		case ACT_METADATA :	// METADATA
 			rc = zvm_metadata();
 			break;
-		case 2 :
+		case ACT_STATUS :	// STATUS
+			if ((rc = check_parm(&zvm)) == 0)
+				rc = zvm_smapi_imageQuery(&zvm);
+			break;
+		case ACT_MONITOR :	// MONITOR
+			rc = 0;
+			break;
+		case ACT_LIST :		// LIST
+			printf("N/A");
+			rc = 0;
+			break;
+		case ACT_HELP :
 			rc = usage();
 	}
 	closelog();
diff --git a/fence/agents/zvm/fence_zvm.h b/fence/agents/zvm/fence_zvm.h
index 3c00c1c..ca18e4d 100644
--- a/fence/agents/zvm/fence_zvm.h
+++ b/fence/agents/zvm/fence_zvm.h
@@ -562,9 +562,11 @@ typedef struct {
 	int	 sd;
 	int	 reason;
 	uint32_t timeOut;
+	uint32_t delay;
 	char	 target[9];
 	char	 authUser[9];
 	char	 authPass[9];
+	char	 node[9];
 	char	 smapiSrv[128];
 } zvm_driver_t;
 
@@ -576,5 +578,6 @@ int zvm_smapi_imageActivate(zvm_driver_t *);
 int zvm_smapi_imageActiveQuery(zvm_driver_t *);
 int zvm_smapi_imageDeactivate(zvm_driver_t *);
 int zvm_smapi_imageRecycle(zvm_driver_t *);
+int zvm_smapi_imageQuery(zvm_driver_t *);
 
 #endif /* FENCE_ZVM_H */
diff --git a/fence/agents/zvm/fence_zvmip.8 b/fence/agents/zvm/fence_zvmip.8
deleted file mode 100644
index 222b483..0000000
--- a/fence/agents/zvm/fence_zvmip.8
+++ /dev/null
@@ -1,86 +0,0 @@
-.TH fence_zvmip 8
-
-.SH NAME
-fence_zvmip - Power Fencing agent for GFS on System z z/VM Clusters using IP interface to SMAPI
-
-.SH SYNOPSIS
-.B
-fence_zvmip
-[\fIOPTION\fR]...
-
-.SH DESCRIPTION
-fence_zvmip is a Power Fencing agent used on a GFS virtual machine in a System z z/VM cluster.
-It uses the TCP/IP SMAPI interface to recycle an active image.
-
-fence_zvmip accepts options on the command line as well as from stdin.
-fence_node sends the options through stdin when it execs the agent.
-fence_zvmip can be run by itself with command line options which is useful
-for testing.
-
-Vendor URL: http://www.sinenomine.net
-
-.SH OPTIONS
-.TP
-\fB-o --action\fP
-Fencing action: "off" - fence off device; "metadata" - display device metadata
-.TP
-\fB-n --plug\fP \fItarget\fP
-Name of target virtual machine to fence
-.TP
-\fB-h --help\fP
-Print out a help message describing available options, then exit.
-.TP
-\fB-a --ip\fP \fIsmapi Server\fP
-Host name or IP address of SMAPI server
-.TP
-\fB-u --username\fP \fISMAPI authorized user\fP
-Name of an authorized SMAPI user
-.TP
-\fB-p --password\fP \fISMAPI authorized user's password\fP
-Password of the authorized SMAPI user
-.TP
-\fB-t --timeout\fP \fIRecycle timeout\fP
-Amount of \fIgrace\fP time to give the virtual machine to shutdown cleanly before being
-forcibly terminated. Currently this is ignored.
-.TP
-\fB-h --help\fP
-Display usage information
-
-.SH STDIN PARAMETERS
-.TP
-\fIagent = < param >\fP
-This option is used by fence_node(8) and is ignored by fence_zvmip.
-.TP
-\fIplug = < plug >\fP
-Name of virtual machine to recycle.
-.TP
-\fIipaddr = < server host name or IP address >\fP
-Host name or IP address of SMAPI server
-.TP
-\fIlogin = < SMAPI authorized user >\fP
-Name of an authorized SMAPI user
-.TP
-\fIpasswd = < SMAPI authorized user's password >\fP
-Password of the authorized SMAPI user
-.TP
-\fItimeout = < shutdown timeout >\fP
-Amount of \fIgrace\fP time to give the virtual machine to shutdown cleanly before being
-forcibly terminated. Currently this is ignored.
-
-.SH SEE ALSO
-fence(8), fenced(8), fence_node(8)
-
-.SH NOTES
-To use this agent the z/VM SMAPI service needs to be configured to allow the virtual
-machine running this agent to connect to it and issue the image_recycle operation.
-This involves updating the VSMWORK1 AUTHLIST VMSYS:VSMWORK1. file. The entry should look
-something similar to this:
-
-.nf
-Column 1                   Column 66                Column 131
-|                          |                        |
-V                          V                        V
-XXXXXXXX                   ALL                      IMAGE_OPERATIONS
-.fi
-
-Where XXXXXXX is the name of the virtual machine used in the authuser field of the request. 
diff --git a/fence/agents/zvm/fence_zvmip.c b/fence/agents/zvm/fence_zvmip.c
index 1fa2119..b16de48 100644
--- a/fence/agents/zvm/fence_zvmip.c
+++ b/fence/agents/zvm/fence_zvmip.c
@@ -48,11 +48,22 @@
 
 #define MIN(a,b)	((a) < (b) ? (a) : (b))
 #define DEFAULT_TIMEOUT 300
+#define DEFAULT_DELAY	0
+
+#define ACT_OFFON 	0
+#define ACT_OFF		1
+#define ACT_ON		2
+#define ACT_METADATA	3
+#define ACT_STATUS	4
+#define ACT_MONITOR	5
+#define ACT_LIST	6
+#define ACT_HELP	7
 
 static int zvm_smapi_reportError(void *, void *);
 
 static struct option longopts[] = {
 	{"action",	required_argument,	NULL, 'o'},
+	{"delay",	required_argument,	NULL, 'd'},
 	{"help",	no_argument,		NULL, 'h'},
 	{"ipaddr",	required_argument,	NULL, 'a'},
 	{"password",	required_argument,	NULL, 'p'},
@@ -62,7 +73,7 @@ static struct option longopts[] = {
 	{NULL,		0,			NULL, 0}
 };
 
-static char *optString = "a:o:hn:p:t:u:";
+static const char *optString = "a:o:hn:p:t:u:";
 
 static int zvm_metadata(void);
 static int usage(void);
@@ -142,6 +153,12 @@ zvm_smapi_imageRecycle(zvm_driver_t *zvm)
 	uint32_t reqId;
 	int	rc;
 
+	/*
+	 * Implement any delay
+	 */ 
+	if (zvm->delay > 0) 
+		sleep(zvm->delay);
+
 	lInPlist = sizeof(*inPlist) + sizeof(*authUser) + strlen(zvm->authUser) +
 		   sizeof(*authPass) + strlen(zvm->authPass) + sizeof(*image) + 
 		   + strlen(zvm->target);
@@ -193,6 +210,276 @@ zvm_smapi_imageRecycle(zvm_driver_t *zvm)
 }
 
 /**
+ * zvm_smapi_imageDeactivate
+ * @zvm: z/VM driver information
+ *
+ * Deactivates a virtual image
+ */
+int
+zvm_smapi_imageDeactivate(zvm_driver_t *zvm)
+{
+	struct _inPlist {
+		int32_t	lPlist;
+		int32_t	lFName;
+		char	fName[16];
+	} __attribute__ ((packed)) *inPlist;
+	struct _authUser {
+		int32_t  lAuthUser;
+		char	 userId[0];
+	} __attribute__ ((packed)) *authUser;
+	struct _authPass {
+		int32_t  lAuthPass;
+		char	 password[0];
+	} __attribute__ ((packed)) *authPass;
+	struct _image {
+		int32_t	lTarget;
+		char    target[0];
+	} __attribute__ ((packed)) *image;
+	struct _deactTime {
+		int32_t lForceTime;
+		char	forceTime[5];
+	} __attribute__ ((__packed__)) *deactTime;
+	int32_t	lInPlist;
+	struct	_outPlist {
+		smapiOutHeader_t hdr;
+		int32_t	nActive;
+		int32_t	nInActive;
+		int32_t	lFail;
+		char	failArray[0];
+	} *outPlist = NULL;
+	void	*pOut = NULL;
+	int32_t	lRsp;
+	uint32_t reqId;
+	int	rc;
+
+	/*
+	 * Implement any delay
+	 */ 
+	if (zvm->delay > 0) 
+		sleep(zvm->delay);
+
+	lInPlist = sizeof(*inPlist) + sizeof(*authUser) + strlen(zvm->authUser) +
+		   sizeof(*authPass) + strlen(zvm->authPass) + sizeof(*image) + 
+		   sizeof(*deactTime) + strlen(zvm->target);
+	inPlist = malloc(lInPlist);
+	if (inPlist != NULL) {
+		authUser =  (void *) ((uintptr_t) inPlist + sizeof(*inPlist));
+		authPass =  (void *) ((uintptr_t) authUser + sizeof(*authUser) +
+			    strlen(zvm->authUser));
+		image    =  (void *) ((uintptr_t) authPass + sizeof(*authPass) + 
+			    strlen(zvm->authPass));
+		deactTime = (void *) ((intptr_t) image + sizeof(*image) + 
+			    strlen(zvm->target));
+		inPlist->lPlist = lInPlist - sizeof(inPlist->lPlist);
+		inPlist->lFName = sizeof(inPlist->fName);
+		memcpy(inPlist->fName, Image_Deactivate, sizeof(inPlist->fName));
+		authUser->lAuthUser = strlen(zvm->authUser);
+		memcpy(authUser->userId, zvm->authUser, strlen(zvm->authUser));
+		authPass->lAuthPass = strlen(zvm->authPass);
+		memcpy(authPass->password, zvm->authPass, strlen(zvm->authPass));
+		image->lTarget = strlen(zvm->target);
+		memcpy(image->target, zvm->target, strlen(zvm->target));
+		deactTime->lForceTime = sizeof(deactTime->forceTime);
+		memcpy(deactTime->forceTime, "IMMED", sizeof(deactTime->forceTime));
+		if ((rc = zvm_smapi_send(zvm, inPlist, &reqId, lInPlist)) != -1) {
+			if ((rc = zvm_smapi_recv(zvm, &pOut, &lRsp)) != -1) {
+				outPlist = pOut;
+				if (outPlist->hdr.rc == 0) {
+					syslog(LOG_INFO, "Deactivation of %s successful",
+					       zvm->target);
+					rc = 0;
+				} else {
+					if ((outPlist->hdr.rc == RCERR_IMAGEOP) &
+					    ((outPlist->hdr.reason == RS_NOT_ACTIVE) |
+					     (outPlist->hdr.reason == RS_BEING_DEACT))) {
+						syslog(LOG_INFO, "Deactivation of %s successful",
+						       zvm->target);
+						rc = 0;
+					} else {
+						rc = outPlist->hdr.rc;
+						zvm->reason = outPlist->hdr.reason;
+						(void) zvm_smapi_reportError(inPlist, outPlist);
+					}
+				}
+			}
+		}
+		free(inPlist);
+		free(outPlist);
+	} else {
+		syslog(LOG_ERR, "%s - cannot allocate parameter list", __func__);
+		rc = -1;
+	}
+	return(rc);
+}
+
+/**
+ * zvm_smapi_imageActivate
+ * @zvm: z/VM driver information
+ *
+ * Deactivates a virtual image
+ */
+int
+zvm_smapi_imageActivate(zvm_driver_t *zvm)
+{
+	struct _inPlist {
+		int32_t	lPlist;
+		int32_t	lFName;
+		char	fName[14];
+	} __attribute__ ((packed)) *inPlist;
+	struct _authUser {
+		int32_t  lAuthUser;
+		char	 userId[0];
+	} __attribute__ ((packed)) *authUser;
+	struct _authPass {
+		int32_t  lAuthPass;
+		char	 password[0];
+	} __attribute__ ((packed)) *authPass;
+	struct _image {
+		int32_t	lTarget;
+		char    target[0];
+	} __attribute__ ((packed)) *image;
+	int32_t	lInPlist;
+	struct	_outPlist {
+		smapiOutHeader_t hdr;
+		int32_t	nActive;
+		int32_t	nInActive;
+		int32_t	lFail;
+		char	failArray[0];
+	} *outPlist = NULL;
+	void	*pOut = NULL;
+	int32_t	lRsp;
+	uint32_t reqId;
+	int	rc;
+
+	/*
+	 * Implement any delay
+	 */ 
+	if (zvm->delay > 0) 
+		sleep(zvm->delay);
+
+	lInPlist = sizeof(*inPlist) + sizeof(*authUser) + strlen(zvm->authUser) +
+		   sizeof(*authPass) + strlen(zvm->authPass) + sizeof(*image) + 
+		   strlen(zvm->target);
+	inPlist = malloc(lInPlist);
+	if (inPlist != NULL) {
+		authUser = (void *) ((uintptr_t) inPlist + sizeof(*inPlist));
+		authPass = (void *) ((uintptr_t) authUser + sizeof(*authUser) +
+			   strlen(zvm->authUser));
+		image    = (void *) ((uintptr_t) authPass + sizeof(*authPass) + 
+			   strlen(zvm->authPass));
+		inPlist->lPlist = lInPlist - sizeof(inPlist->lPlist);
+		inPlist->lFName = sizeof(inPlist->fName);
+		memcpy(inPlist->fName, Image_Activate, sizeof(inPlist->fName));
+		authUser->lAuthUser = strlen(zvm->authUser);
+		memcpy(authUser->userId, zvm->authUser, strlen(zvm->authUser));
+		authPass->lAuthPass = strlen(zvm->authPass);
+		memcpy(authPass->password, zvm->authPass, strlen(zvm->authPass));
+		image->lTarget = strlen(zvm->target);
+		memcpy(image->target, zvm->target, strlen(zvm->target));
+		if ((rc = zvm_smapi_send(zvm, inPlist, &reqId, lInPlist)) != -1) {
+			if ((rc = zvm_smapi_recv(zvm, &pOut, &lRsp)) != -1) {
+				outPlist = pOut;
+				if (outPlist->hdr.rc == 0) {
+					syslog(LOG_INFO, "Activation of %s successful",
+					       zvm->target);
+					rc = 0;
+				} else {
+					if ((outPlist->hdr.rc == RCERR_IMAGEOP) &
+					     (outPlist->hdr.reason == RS_ALREADY_ACTIVE)) {
+						syslog(LOG_INFO, "Activation of %s successful",
+						       zvm->target);
+						rc = 0;
+					} else {
+						rc = outPlist->hdr.rc;
+						zvm->reason = outPlist->hdr.reason;
+						(void) zvm_smapi_reportError(inPlist, outPlist);
+					}
+				}
+			}
+		}
+		free(inPlist);
+		free(outPlist);
+	} else {
+		syslog(LOG_ERR, "%s - cannot allocate parameter list", __func__);
+		rc = -1;
+	}
+	return(rc);
+}
+
+/**
+ * zvm_smapi_imageQuery
+ * @zvm: z/VM driver information
+ *
+ * Queries the state of a virtual image
+ */
+int
+zvm_smapi_imageQuery(zvm_driver_t *zvm)
+{
+	struct _inPlist {
+		int32_t	lPlist;
+		int32_t	lFName;
+		char	fName[18];
+		int32_t lUser;
+		int32_t lPass;
+		int32_t	lTarget;
+		char	target[0];
+	} __attribute__ ((__packed__)) *inPlist;
+	int32_t	lInPlist;
+	struct	_outPlist {
+		smapiOutHeader_t hdr;
+		int32_t	lNames;
+		char	nameArray[0];
+	} *outPlist = NULL;
+	void	*pOut = NULL;
+	int32_t	lRsp;
+	uint32_t reqId;
+	int	rc;
+
+	/*
+	 * Implement any delay
+	 */ 
+	if (zvm->delay > 0) 
+		sleep(zvm->delay);
+
+	lInPlist = sizeof(*inPlist) + strlen(zvm->target);
+	inPlist = malloc(lInPlist);
+	if (inPlist != NULL) {
+		inPlist->lPlist = lInPlist - sizeof(inPlist->lPlist);
+		inPlist->lFName = sizeof(inPlist->fName);
+		memcpy(inPlist->fName, Image_Status_Query, sizeof(inPlist->fName));
+		inPlist->lUser = inPlist->lPass = 0;
+		inPlist->lTarget = strlen(zvm->target);
+		memcpy(inPlist->target, zvm->target, inPlist->lTarget);
+		if ((rc = zvm_smapi_send(zvm, inPlist, &reqId, lInPlist)) != -1) {
+			if ((rc = zvm_smapi_recv(zvm, &pOut, &lRsp)) != -1) {
+				outPlist = pOut;
+				if (outPlist->hdr.rc == 0) {
+					if (outPlist->hdr.reason == 0) {
+						syslog(LOG_INFO, "Node %s is active",
+						       zvm->target);
+						rc = 0;
+					} else { 
+						syslog(LOG_INFO, "Node %s is inactive",
+						       zvm->target);
+						rc = 2;
+					}
+				} else {
+					rc = 1;
+					zvm->reason = outPlist->hdr.reason;
+					(void) zvm_smapi_reportError(inPlist, outPlist);
+				}
+			}
+		}
+		free(inPlist);
+		free(outPlist);
+	} else {
+		syslog(LOG_ERR, "%s - cannot allocate parameter list", __func__);
+		rc = -1;
+	}
+	return(rc);
+}
+
+/**
  * zvm_smapi_send:
  * @zvm: z/VM driver information
  * @reqid: Returned request id
@@ -374,7 +661,7 @@ get_options_stdin (zvm_driver_t *zvm)
 		*arg;
 	int32_t lSrvName,
 		lTarget;
-	int	fence = 0;
+	int	fence = ACT_OFFON;
 
 	while (fgets (buf, sizeof (buf), stdin) != 0) {
 		if (trim(buf) == 0) {
@@ -397,12 +684,22 @@ get_options_stdin (zvm_driver_t *zvm)
 			continue;
 
 		if (!strcasecmp (opt, "action")) {
-			if (strcasecmp(arg, "off") == 0) {
-				fence = 0;
+			if (strcasecmp(arg, "reboot") == 0) {
+				fence = ACT_OFFON;
+			} else if (strcasecmp(arg, "off") == 0) {
+				fence = ACT_OFF;
+			} else if (strcasecmp(arg, "on") == 0) {
+				fence = ACT_ON;
 			} else if (strcasecmp(arg, "metadata") == 0) {
-				fence = 1;
+				fence = ACT_METADATA;
+			} else if (strcasecmp(arg, "status") == 0) {
+				fence = ACT_STATUS;
+			} else if (strcasecmp(arg, "monitor") == 0) {
+				fence = ACT_MONITOR;
+			} else if (strcasecmp(arg, "list") == 0) {
+				fence = ACT_LIST;
 			} else {
-				fence = 2;
+				fence = ACT_HELP;
 			}
 		} else if (!strcasecmp (opt, "ipaddr")) {
 			lSrvName = MIN(strlen(arg), sizeof(zvm->smapiSrv)-1);
@@ -429,7 +726,7 @@ get_options_stdin (zvm_driver_t *zvm)
 				zvm->timeOut = DEFAULT_TIMEOUT;
 			}
 		} else if (!strcasecmp (opt, "help")) {
-			fence = 2;
+			fence = ACT_HELP;
 		}
 	}
 	return(fence);
@@ -446,7 +743,7 @@ static int
 get_options(int argc, char **argv, zvm_driver_t *zvm)
 {
 	int	c,
-		fence = 0;
+		fence = ACT_OFFON;
 	int32_t	lSrvName,
 		lTarget;
 	char	*endPtr;
@@ -462,12 +759,22 @@ get_options(int argc, char **argv, zvm_driver_t *zvm)
 			memcpy(zvm->target, optarg, lTarget);
 			break;
 		case 'o' :
-			if (strcasecmp(optarg, "off") == 0) {
-				fence = 0;
+			if (strcasecmp(optarg, "reboot") == 0) {
+				fence = ACT_OFFON;
+			} else if (strcasecmp(optarg, "off") == 0) {
+				fence = ACT_OFF;
+			} else if (strcasecmp(optarg, "on") == 0) {
+				fence = ACT_ON;
 			} else if (strcasecmp(optarg, "metadata") == 0) {
-				fence = 1;
+				fence = ACT_METADATA;
+			} else if (strcasecmp(optarg, "status") == 0) {
+				fence = ACT_STATUS;
+			} else if (strcasecmp(optarg, "monitor") == 0) {
+				fence = ACT_MONITOR;
+			} else if (strcasecmp(optarg, "list") == 0) {
+				fence = ACT_LIST;
 			} else {
-				fence = 2;
+				fence = ACT_HELP;
 			}
 			break;
 		case 'p' :
@@ -487,8 +794,17 @@ get_options(int argc, char **argv, zvm_driver_t *zvm)
 				zvm->timeOut = DEFAULT_TIMEOUT;
 			}
 			break;
+		case 'd' :
+			zvm->delay = strtoul(optarg, &endPtr, 10);
+			if (*endPtr != 0) {
+				syslog(LOG_WARNING, "Invalid delay value specified: %s - "
+				       "defaulting to %d", 
+				       optarg, DEFAULT_DELAY);
+				zvm->delay = DEFAULT_DELAY;
+			}
+			break;
 		default :
-			fence = 2;
+			fence = ACT_HELP;
 		}
 	}
 	return(fence);
@@ -508,6 +824,7 @@ zvm_metadata()
 	fprintf (stdout, "<longdesc>");
 	fprintf (stdout, "The fence_zvm agent is intended to be used with with z/VM SMAPI service via TCP/IP");
 	fprintf (stdout, "</longdesc>\n");
+	fprintf (stdout, "<vendor-url>http://www.ibm.com</vendor-url>\n");
 
 	fprintf (stdout, "<parameters>\n");
 
@@ -529,14 +846,14 @@ zvm_metadata()
 	fprintf (stdout, "\t\t<getopt mixed=\"-u, --username\" />\n");
 	fprintf (stdout, "\t\t<content type=\"string\" />\n");
 	fprintf (stdout, "\t\t<shortdesc lang=\"en\">%s</shortdesc>\n",
-	     "Name of authorized SMAPI user\n");
+	     "Name of authorized SMAPI user");
 	fprintf (stdout, "\t</parameter>\n");
 
 	fprintf (stdout, "\t<parameter name=\"passwd\" unique=\"1\" required=\"1\">\n");
 	fprintf (stdout, "\t\t<getopt mixed=\"-p, --password\" />\n");
 	fprintf (stdout, "\t\t<content type=\"string\" />\n");
 	fprintf (stdout, "\t\t<shortdesc lang=\"en\">%s</shortdesc>\n",
-	     "Password of authorized SMAPI user\n");
+	     "Password of authorized SMAPI user");
 	fprintf (stdout, "\t</parameter>\n");
 
 	fprintf (stdout, "\t<parameter name=\"action\" unique=\"1\" required=\"0\">\n");
@@ -546,6 +863,13 @@ zvm_metadata()
 	     "Fencing action");
 	fprintf (stdout, "\t</parameter>\n");
 
+	fprintf (stdout, "\t<parameter name=\"delay\" unique=\"1\" required=\"0\">\n");
+	fprintf (stdout, "\t\t<getopt mixed=\"--delay\" />\n");
+	fprintf (stdout, "\t\t<content type=\"string\" default=\"0\" />\n");
+	fprintf (stdout, "\t\t<shortdesc lang=\"en\">%s</shortdesc>\n",
+	     "Time to delay fencing action in seconds");
+	fprintf (stdout, "\t</parameter>\n");
+
 	fprintf (stdout, "\t<parameter name=\"usage\" unique=\"1\" required=\"0\">\n");
 	fprintf (stdout, "\t\t<getopt mixed=\"-h, --help\" />\n");
 	fprintf (stdout, "\t\t<content type=\"boolean\" />\n");
@@ -557,7 +881,12 @@ zvm_metadata()
 
 	fprintf (stdout, "<actions>\n");
 	fprintf (stdout, "\t<action name=\"off\" />\n");
+	fprintf (stdout, "\t<action name=\"on\" automatic=\"0\" />\n");
+	fprintf (stdout, "\t<action name=\"list\" />\n");
 	fprintf (stdout, "\t<action name=\"metadata\" />\n");
+	fprintf (stdout, "\t<action name=\"monitor\" />\n");
+	fprintf (stdout, "\t<action name=\"status\" />\n");
+	fprintf (stdout, "\t<action name=\"reboot\" />\n");
 	fprintf (stdout, "</actions>\n");
 
 	fprintf (stdout, "</resource-agent>\n");
@@ -575,7 +904,9 @@ usage()
 {
 	fprintf(stderr,"Usage: fence_zvmip [options]\n\n"
 		"\tWhere [options] =\n"
-		"\t-o --action [action] - \"off\", \"metadata\"\n"
+		"\t-o --action [action] - \"off\", \"on\", \"list\", \"metadata\", "
+					 "\"monitor\", \"reboot\", \"status\"\n"
+		"\t--delay [seconds]    - Time to delay fencing action in seconds\n"
 		"\t-n --plug [target]   - Name of virtual machine to fence\n"
 		"\t-a --ip [server]     - IP Name/Address of SMAPI Server\n"
 		"\t-u --username [user] - Name of autorized SMAPI user\n"
@@ -629,6 +960,7 @@ main(int argc, char **argv)
 	openlog ("fence_zvmip", LOG_CONS|LOG_PID, LOG_DAEMON);
 	memset(&zvm, 0, sizeof(zvm));
 	zvm.timeOut = DEFAULT_TIMEOUT;
+	zvm.delay   = DEFAULT_DELAY;
 
 	if (argc > 1)
 		fence = get_options(argc, argv, &zvm);
@@ -636,14 +968,32 @@ main(int argc, char **argv)
 		fence = get_options_stdin(&zvm);
 
 	switch(fence) {
-		case 0 :
+		case ACT_OFFON :	// OFFON
 			if ((rc = check_parm(&zvm)) == 0)
 				rc = zvm_smapi_imageRecycle(&zvm);
 			break;
-		case 1 :
+		case ACT_OFF :		// OFF
+			if ((rc = check_parm(&zvm)) == 0)
+				rc = zvm_smapi_imageDeactivate(&zvm);
+			break;
+		case ACT_ON :		// ON
+			if ((rc = check_parm(&zvm)) == 0)
+				rc = zvm_smapi_imageActivate(&zvm);
+			break;
+		case ACT_METADATA :	// METADATA
 			rc = zvm_metadata();
 			break;
-		case 2 :
+		case ACT_STATUS :	// STATUS
+			if ((rc = check_parm(&zvm)) == 0)
+				rc = zvm_smapi_imageQuery(&zvm);
+			break;
+		case ACT_MONITOR :	// MONITOR
+			rc = 0;
+			break;
+		case ACT_LIST :
+			printf("N/A");
+			break;
+		case ACT_HELP :
 			rc = usage();
 	}
 	closelog();
diff --git a/fence/agents/zvm/fence_zvmip.py b/fence/agents/zvm/fence_zvmip.py
new file mode 100644
index 0000000..6d09b68
--- /dev/null
+++ b/fence/agents/zvm/fence_zvmip.py
@@ -0,0 +1,175 @@
+#!/usr/bin/python -tt
+
+import sys
+import atexit
+import socket
+import struct
+import logging
+sys.path.append("@FENCEAGENTSLIBDIR@")
+from fencing import *
+from fencing import fail, fail_usage, run_delay, EC_LOGIN_DENIED, EC_TIMED_OUT
+
+#BEGIN_VERSION_GENERATION
+RELEASE_VERSION=""
+REDHAT_COPYRIGHT=""
+BUILD_DATE=""
+#END_VERSION_GENERATION
+
+INT4 = 4
+
+def open_socket(options):
+	try:
+		if "--inet6-only" in options:
+			protocol = socket.AF_INET6
+		elif "--inet4-only" in options:
+			protocol = socket.AF_INET
+		else:
+			protocol = 0
+		(_, _, _, _, addr) = socket.getaddrinfo( \
+				options["--ip"], options["--ipport"], protocol,
+				0, socket.IPPROTO_TCP, socket.AI_PASSIVE
+				)[0]
+	except socket.gaierror:
+		fail(EC_LOGIN_DENIED)
+
+	conn = socket.socket()
+	conn.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
+	conn.settimeout(float(options["--shell-timeout"]))
+	try:
+		conn.connect(addr)
+	except socket.error:
+		fail(EC_LOGIN_DENIED)
+
+	return conn
+
+def smapi_pack_string(string):
+	return struct.pack("!i%ds" % (len(string)), len(string), string)
+
+def prepare_smapi_command(options, smapi_function, additional_args):
+	packet_size = 3*INT4 + len(smapi_function) + len(options["--username"]) + len(options["--password"])
+	for arg in additional_args:
+		packet_size += INT4 + len(arg)
+
+	command = struct.pack("!i", packet_size)
+	command += smapi_pack_string(smapi_function)
+	command += smapi_pack_string(options["--username"])
+	command += smapi_pack_string(options["--password"])
+	for arg in additional_args:
+		command += smapi_pack_string(arg)
+
+	return command
+
+def get_power_status(conn, options):
+	del conn
+
+	# '*' = list all active images
+	(return_code, reason_code, images_active) = \
+			get_list_of_images(options, "Image_Status_Query", "*")
+	logging.debug("Image_Status_Query results are (%d,%d)", return_code, reason_code)
+	(return_code, reason_code, images_defined) = \
+			get_list_of_images(options, "Image_Name_Query_DM", options["--username"])
+	logging.debug("Image_Name_Query_DM results are (%d,%d)", return_code, reason_code)
+
+	if ["list", "monitor"].count(options["--action"]) == 1:
+		return dict([(i, ("", "on" if i in images_active else "off")) for i in images_defined])
+	else:
+		status = "error"
+		if options["--plug"].upper() in images_defined:
+			if options["--plug"].upper() in images_active:
+				status = "on"
+			else:
+				status = "off"
+		return status
+
+def set_power_status(conn, options):
+	conn = open_socket(options)
+
+	packet = None
+	if options["--action"] == "on":
+		packet = prepare_smapi_command(options, "Image_Activate", [options["--plug"]])
+	elif options["--action"] == "off":
+		packet = prepare_smapi_command(options, "Image_Deactivate", [options["--plug"], "IMMED"])
+	conn.send(packet)
+
+	request_id = struct.unpack("!i", conn.recv(INT4))[0]
+	(output_len, request_id, return_code, reason_code) = struct.unpack("!iiii", conn.recv(INT4 * 4))
+	logging.debug("Image_(De)Activate results are (%d,%d)", return_code, reason_code)
+
+	conn.close()
+	return
+
+def get_list_of_images(options, command, data_as_plug):
+	conn = open_socket(options)
+
+	packet = prepare_smapi_command(options, command, [data_as_plug])
+	conn.send(packet)
+
+	request_id = struct.unpack("!i", conn.recv(INT4))[0]
+	(output_len, request_id, return_code, reason_code) = struct.unpack("!iiii", conn.recv(INT4 * 4))
+	images = set()
+
+	if output_len > 3*INT4:
+		array_len = struct.unpack("!i", conn.recv(INT4))[0]
+		data = ""
+
+		while True:
+			read_data = conn.recv(1024, socket.MSG_WAITALL)
+			data += read_data
+			if array_len == len(data):
+				break
+			elif not read_data:
+				logging.error("Failed: Not enough data read from socket")
+				fail(EC_TIMED_OUT)
+
+		parsed_len = 0
+		while parsed_len < array_len:
+			string_len = struct.unpack("!i", data[parsed_len:parsed_len+INT4])[0]
+			parsed_len += INT4
+			image_name = struct.unpack("!%ds" % (string_len), data[parsed_len:parsed_len+string_len])[0]
+			parsed_len += string_len
+			images.add(image_name)
+
+	conn.close()
+	return (return_code, reason_code, images)
+
+def main():
+	device_opt = ["ipaddr", "login", "passwd", "port", "method"]
+
+	atexit.register(atexit_handler)
+
+	all_opt["ipport"]["default"] = "44444"
+	all_opt["shell_timeout"]["default"] = "5.0"
+	options = check_input(device_opt, process_input(device_opt), other_conditions=True)
+
+	if len(options.get("--plug", "")) > 8:
+		fail_usage("Failed: Name of image can not be longer than 8 characters")
+
+        if options["--action"] == "validate-all":
+                sys.exit(0)
+
+	docs = {}
+	docs["shortdesc"] = "Fence agent for use with z/VM Virtual Machines"
+	docs["longdesc"] = """The fence_zvm agent is intended to be used with with z/VM SMAPI service via TCP/IP
+
+To  use this agent the z/VM SMAPI service needs to be configured to allow the virtual machine running this agent to connect to it and issue
+the image_recycle operation.  This involves updating the VSMWORK1 AUTHLIST VMSYS:VSMWORK1. file. The entry should look something similar to
+this:
+
+Column 1                   Column 66                Column 131
+
+   |                          |                        |
+   V                          V                        V
+
+XXXXXXXX                      ALL                      IMAGE_OPERATIONS
+
+Where XXXXXXX is the name of the virtual machine used in the authuser field of the request.
+"""
+	docs["vendorurl"] = "http://www.ibm.com"
+	show_docs(options, docs)
+
+	run_delay(options)
+	result = fence_action(None, options, set_power_status, get_power_status, get_power_status)
+	sys.exit(result)
+
+if __name__ == "__main__":
+	main()
diff --git a/make/ac_python_module.m4 b/make/ac_python_module.m4
new file mode 100644
index 0000000..32b9d72
--- /dev/null
+++ b/make/ac_python_module.m4
@@ -0,0 +1,30 @@
+dnl @synopsis AC_PYTHON_MODULE(modname[, fatal])
+dnl
+dnl Checks for Python module.
+dnl
+dnl If fatal is non-empty then absence of a module will trigger an
+dnl error.
+dnl
+dnl @category InstalledPackages
+dnl @author Andrew Collier <colliera at nu.ac.za>.
+dnl @version 2004-07-14
+dnl @license AllPermissive
+
+AC_DEFUN([AC_PYTHON_MODULE],[
+	AC_MSG_CHECKING(python module: $1)
+	python -c "import $1" 2>/dev/null
+	if test $? -eq 0;
+	then
+		AC_MSG_RESULT(yes)
+		eval AS_TR_CPP(HAVE_PYMOD_$1)=yes
+	else
+		AC_MSG_RESULT(no)
+		eval AS_TR_CPP(HAVE_PYMOD_$1)=no
+		#
+		if test -n "$2"
+		then
+			AC_MSG_ERROR(failed to find required module $1)
+			exit 1
+		fi
+	fi
+])
diff --git a/make/agentccheck.mk b/make/agentccheck.mk
new file mode 100644
index 0000000..46e2055
--- /dev/null
+++ b/make/agentccheck.mk
@@ -0,0 +1,22 @@
+TEMPFILE:=$(shell mktemp)
+DATADIR:=$(abs_top_srcdir)/tests/data/metadata
+
+check: $(TARGET:%=xml-check.%) $(SYMTARGET:%=xml-check.%)
+
+xml-check.%: %
+	$(eval INPUT=$(subst xml-check.,,$@))
+	./$(INPUT) -o metadata > $(TEMPFILE)
+	diff $(TEMPFILE) $(DATADIR)/$(INPUT).xml
+	rm $(TEMPFILE)
+
+xml-upload.%: %
+	$(eval INPUT=$(subst xml-upload.,,$@))
+	./$(INPUT) -o metadata > $(DATADIR)/$(INPUT).xml
+
+# If test will fail, rerun fence agents to show problems
+delay-check.%: %
+	$(eval INPUT=$(subst delay-check.,,$@))
+	test `/usr/bin/time -f "%e" ./$(INPUT) --delay 10 $(FENCE_TEST_ARGS) -- 2>&1 |\
+	sed 's/\.//' | tail -n 1` -ge 1000 || \
+	/usr/bin/time -f "%e" ./$(INPUT) --delay 0 $(FENCE_TEST_ARGS) --
+
diff --git a/make/agentpycheck.mk b/make/agentpycheck.mk
new file mode 100644
index 0000000..ba573f9
--- /dev/null
+++ b/make/agentpycheck.mk
@@ -0,0 +1,31 @@
+TEMPFILE:=$(shell mktemp)
+#DATADIR:=$(abs_top_builddir)/tests/data/metadata
+DATADIR:=$(abs_top_srcdir)/tests/data/metadata
+AWK_VAL='BEGIN {store=-1} /name=\"store_path\"/ {store=2} {if (store!=0) {print}; store--}'
+
+check: $(TARGET:%=xml-check.%) $(SYMTARGET:%=xml-check.%) $(TARGET:%=delay-check.%) $(TARGET:%=rng-check.%)
+
+xml-check.%: %
+	$(eval INPUT=$(subst xml-check.,,$@))
+	PYTHONPATH=$(abs_srcdir)/../lib:$(abs_builddir)/../lib python ./$(INPUT) -o metadata | $(AWK) $(AWK_VAL) > $(TEMPFILE)
+	diff $(TEMPFILE) $(DATADIR)/$(INPUT).xml
+	rm $(TEMPFILE)
+
+xml-upload.%: %
+	$(eval INPUT=$(subst xml-upload.,,$@))
+	PYTHONPATH=$(abs_srcdir)/../lib:$(abs_builddir)/../lib python ./$(INPUT) -o metadata | $(AWK) $(AWK_VAL) > $(DATADIR)/$(INPUT).xml
+
+# If test will fail, rerun fence agents to show problems
+delay-check.%: %
+	$(eval INPUT=$(subst delay-check.,,$@))
+	test `PYTHONPATH=$(abs_srcdir)/../lib:$(abs_builddir)/../lib /usr/bin/time -f "%e" \
+	python ./$(INPUT) --delay 10 $(FENCE_TEST_ARGS) -- 2>&1 |\
+	sed 's/\.//' | tail -n 1` -ge 1000 || \
+	PYTHONPATH=$(abs_srcdir)/../lib:$(abs_builddir)/../lib /usr/bin/time -f "%e" \
+	python ./$(INPUT) --delay 0 $(FENCE_TEST_ARGS) --
+
+rng-check.%: %
+	PYTHONPATH=$(abs_srcdir)/../lib:$(abs_builddir)/../lib python ./$(INPUT) -o metadata | \
+	/usr/bin/xsltproc ${abs_top_srcdir}/fence/agents/lib/fence2rng.xsl - | \
+	sed -e 's/ rha:description=/ description=/g' -e 's/ rha:name=/ name=/g' | \
+	xmllint --nsclean --noout -
diff --git a/make/fencebuild.mk b/make/fencebuild.mk
index 819ac36..3a035e9 100644
--- a/make/fencebuild.mk
+++ b/make/fencebuild.mk
@@ -5,15 +5,32 @@ $(TARGET): $(SRC)
 		$(abs_srcdir) $@ | \
 	sed \
 		-e 's#@''FENCEAGENTSLIBDIR@#${FENCEAGENTSLIBDIR}#g' \
-		-e 's#@''SNMPBIN@#${SNMPBIN}#g' \
 		-e 's#@''LOGDIR@#${LOGDIR}#g' \
 		-e 's#@''SBINDIR@#${sbindir}#g' \
 		-e 's#@''LIBEXECDIR@#${libexecdir}#g' \
 		-e 's#@''IPMITOOL_PATH@#${IPMITOOL_PATH}#g' \
 		-e 's#@''AMTTOOL_PATH@#${AMTTOOL_PATH}#g' \
 		-e 's#@''GNUTLSCLI_PATH@#${GNUTLSCLI_PATH}#g' \
+		-e 's#@''COROSYNC_CMAPCTL_PATH@#${COROSYNC_CMAPCTL_PATH}#g' \
+		-e 's#@''SG_PERSIST_PATH@#${SG_PERSIST_PATH}#g' \
+		-e 's#@''SG_TURS_PATH@#${SG_TURS_PATH}#g' \
+		-e 's#@''VGS_PATH@#${VGS_PATH}#g' \
+		-e 's#@''SUDO_PATH@#${SUDO_PATH}#g' \
+		-e 's#@''SSH_PATH@#${SSH_PATH}#g' \
+		-e 's#@''TELNET_PATH@#${TELNET_PATH}#g' \
+		-e 's#@''MPATH_PATH@#${MPATH_PATH}#g' \
+		-e 's#@''STORE_PATH@#${CLUSTERVARRUN}#g' \
+		-e 's#@''SUDO_PATH@#${SUDO_PATH}#g' \
+		-e 's#@''SNMPWALK_PATH@#${SNMPWALK_PATH}#g' \
+		-e 's#@''SNMPSET_PATH@#${SNMPSET_PATH}#g' \
+		-e 's#@''SNMPGET_PATH@#${SNMPGET_PATH}#g' \
 	> $@
 
 	if [ 0 -eq `echo "$(SRC)" | grep fence_ &> /dev/null; echo $$?` ]; then \
 		PYTHONPATH=$(abs_srcdir)/../lib:$(abs_builddir)/../lib $(top_srcdir)/fence/agents/lib/check_used_options.py $@; \
 	else true ; fi
+
+clean: clean-man
+	rm -f $(TARGET) $(SYMTARGET) *.pyc *.wiki
+
+clean-local: clean
\ No newline at end of file
diff --git a/make/fenceman.mk b/make/fenceman.mk
index d4f0377..c3360b7 100644
--- a/make/fenceman.mk
+++ b/make/fenceman.mk
@@ -1,9 +1,10 @@
 %.8: $(TARGET) $(top_srcdir)/fence/agents/lib/fence2man.xsl
 	set -e && \
 	PYTHONPATH=$(abs_srcdir)/../lib:$(abs_builddir)/../lib \
-		python $^ -o metadata > .$@.tmp && \
+		python $(@:%.8=%) -o metadata > .$@.tmp && \
 	xmllint --noout --relaxng $(abs_srcdir)/../lib/metadata.rng .$@.tmp && \
 	xsltproc $(top_srcdir)/fence/agents/lib/fence2man.xsl .$@.tmp > $@
+	xsltproc $(top_srcdir)/fence/agents/lib/fence2wiki.xsl .$@.tmp | grep -v '<?xml' > $(@:%.8=%.wiki)
 
 clean-man:
-	rm -f *.8 .*.8.tmp
+	rm -f *.8 .*.8.tmp *.wiki
diff --git a/make/fencemanc.mk b/make/fencemanc.mk
index 27e1aae..53156c5 100644
--- a/make/fencemanc.mk
+++ b/make/fencemanc.mk
@@ -3,6 +3,7 @@
 		./$^ -o metadata > .$@.tmp && \
 	xmllint --noout --relaxng $(top_srcdir)/fence/agents/lib/metadata.rng .$@.tmp && \
 	xsltproc $(top_srcdir)/fence/agents/lib/fence2man.xsl .$@.tmp > $@
+	xsltproc $(top_srcdir)/fence/agents/lib/fence2wiki.xsl .$@.tmp | grep -v '<?xml' > $(@:%.8=%.wiki)
 
 clean-man:
-	rm -f *.8 .*.8.tmp
+	rm -f *.8 .*.8.tmp *.wiki
diff --git a/make/fencemanperl.mk b/make/fencemanperl.mk
index ed7c9cc..0141aa8 100644
--- a/make/fencemanperl.mk
+++ b/make/fencemanperl.mk
@@ -3,6 +3,7 @@
 		perl $(TARGET) -o metadata > .$@.tmp && \
 	xmllint --noout --relaxng $(top_srcdir)/fence/agents/lib/metadata.rng .$@.tmp && \
 	xsltproc $(top_srcdir)/fence/agents/lib/fence2man.xsl .$@.tmp > $@
+	xsltproc $(top_srcdir)/fence/agents/lib/fence2wiki.xsl .$@.tmp | grep -v '<?xml' > $(@:%.8=%.wiki)
 
 clean-man:
-	rm -f *.8 .*.8.tmp
+	rm -f *.8 .*.8.tmp *.wiki
diff --git a/tests/data/metadata/fence_alom.xml b/tests/data/metadata/fence_alom.xml
new file mode 100644
index 0000000..1c89991
--- /dev/null
+++ b/tests/data/metadata/fence_alom.xml
@@ -0,0 +1,131 @@
+<?xml version="1.0" ?>
+<resource-agent name="fence_alom" shortdesc="Fence agent for Sun ALOM" >
+<longdesc>fence_alom is an I/O Fencing agent which can be used with ALOM connected machines.</longdesc>
+<vendor-url>http://www.sun.com</vendor-url>
+<parameters>
+	<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="cmd_prompt" unique="0" required="0">
+		<getopt mixed="-c, --command-prompt=[prompt]" />
+		<content type="string" default="['sc\\>\\ ']"  />
+		<shortdesc lang="en">Force Python regex for command prompt</shortdesc>
+	</parameter>
+	<parameter name="identity_file" unique="0" required="0">
+		<getopt mixed="-k, --identity-file=[filename]" />
+		<content type="string"  />
+		<shortdesc lang="en">Identity file for ssh</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="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</shortdesc>
+	</parameter>
+	<parameter name="ipport" unique="0" required="0">
+		<getopt mixed="-u, --ipport=[port]" />
+		<content type="string" default="22"  />
+		<shortdesc lang="en">TCP/UDP port to use for connection with device</shortdesc>
+	</parameter>
+	<parameter name="login" unique="0" required="1">
+		<getopt mixed="-l, --username=[name]" />
+		<content type="string"  />
+		<shortdesc lang="en">Login Name</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="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="secure" unique="0" required="0">
+		<getopt mixed="-x, --ssh" />
+		<content type="boolean" default="1"  />
+		<shortdesc lang="en">SSH connection</shortdesc>
+	</parameter>
+	<parameter name="ssh_options" unique="0" required="0">
+		<getopt mixed="--ssh-options=[options]" />
+		<content type="string"  />
+		<shortdesc lang="en">SSH options to use</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="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="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="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="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>
+	<parameter name="ssh_path" unique="0" required="0">
+		<getopt mixed="--ssh-path=[path]" />
+		<content type="string" default="/usr/bin/ssh"  />
+		<shortdesc lang="en">Path to ssh binary</shortdesc>
+	</parameter>
+</parameters>
+<actions>
+	<action name="on" automatic="0"/>
+	<action name="off" />
+	<action name="reboot" />
+	<action name="status" />
+	<action name="monitor" />
+	<action name="metadata" />
+	<action name="validate-all" />
+</actions>
+</resource-agent>
diff --git a/tests/data/metadata/fence_amt.xml b/tests/data/metadata/fence_amt.xml
new file mode 100644
index 0000000..f6d1757
--- /dev/null
+++ b/tests/data/metadata/fence_amt.xml
@@ -0,0 +1,135 @@
+<?xml version="1.0" ?>
+<resource-agent name="fence_amt" shortdesc="Fence agent for AMT" >
+<longdesc>fence_amt is an I/O Fencing agent which can be used with Intel AMT. This agent calls support software amttool(http://www.kraxel.org/cgit/amtterm/).</longdesc>
+<vendor-url>http://www.intel.com/</vendor-url>
+<parameters>
+	<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="boot_option" unique="0" required="0">
+		<getopt mixed="-b, --boot-option=[option]" />
+		<content type="select"  >
+			<option value="pxe" />
+			<option value="hd" />
+			<option value="hdsafe" />
+			<option value="cd" />
+			<option value="diag" />
+		</content>
+		<shortdesc lang="en">Change the default boot behavior of the machine.</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="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</shortdesc>
+	</parameter>
+	<parameter name="ipport" unique="0" required="0">
+		<getopt mixed="-u, --ipport=[port]" />
+		<content type="string" default="16994"  />
+		<shortdesc lang="en">TCP/UDP port to use for connection with device</shortdesc>
+	</parameter>
+	<parameter name="method" unique="0" required="0">
+		<getopt mixed="-m, --method=[method]" />
+		<content type="select" default="onoff"  >
+			<option value="onoff" />
+			<option value="cycle" />
+		</content>
+		<shortdesc lang="en">Method to fence (onoff|cycle)</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="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="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="amttool_path" unique="0" required="0">
+		<getopt mixed="--amttool-path=[path]" />
+		<content type="string" default="/usr/bin/amttool"  />
+		<shortdesc lang="en">Path to amttool binary</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="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="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="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>
+	<parameter name="sudo" unique="0" required="0">
+		<getopt mixed="--use-sudo" />
+		<content type="boolean"  />
+		<shortdesc lang="en">Use sudo (without password) when calling 3rd party sotfware.</shortdesc>
+	</parameter>
+	<parameter name="sudo_path" unique="0" required="0">
+		<getopt mixed="--sudo-path=[path]" />
+		<content type="string" default="/usr/bin/sudo"  />
+		<shortdesc lang="en">Path to sudo binary</shortdesc>
+	</parameter>
+</parameters>
+<actions>
+	<action name="on" automatic="0"/>
+	<action name="off" />
+	<action name="reboot" />
+	<action name="status" />
+	<action name="monitor" />
+	<action name="metadata" />
+	<action name="validate-all" />
+</actions>
+</resource-agent>
diff --git a/tests/data/metadata/fence_apc.xml b/tests/data/metadata/fence_apc.xml
new file mode 100644
index 0000000..c5df0a5
--- /dev/null
+++ b/tests/data/metadata/fence_apc.xml
@@ -0,0 +1,153 @@
+<?xml version="1.0" ?>
+<resource-agent name="fence_apc" shortdesc="Fence agent for APC over telnet/ssh" >
+<longdesc>fence_apc is an I/O Fencing agent which can be used with the APC network power switch. It logs into device via telnet/ssh  and reboots a specified outlet. Lengthy telnet/ssh connections should be avoided while a GFS cluster  is  running  because  the  connection will block any necessary fencing actions.</longdesc>
+<vendor-url>http://www.apc.com</vendor-url>
+<parameters>
+	<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="cmd_prompt" unique="0" required="0">
+		<getopt mixed="-c, --command-prompt=[prompt]" />
+		<content type="string" default="['\n>', '\napc>']"  />
+		<shortdesc lang="en">Force Python regex for command prompt</shortdesc>
+	</parameter>
+	<parameter name="identity_file" unique="0" required="0">
+		<getopt mixed="-k, --identity-file=[filename]" />
+		<content type="string"  />
+		<shortdesc lang="en">Identity file for ssh</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="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</shortdesc>
+	</parameter>
+	<parameter name="ipport" unique="0" required="0">
+		<getopt mixed="-u, --ipport=[port]" />
+		<content type="string" default="23"  />
+		<shortdesc lang="en">TCP/UDP port to use for connection with device</shortdesc>
+	</parameter>
+	<parameter name="login" unique="0" required="1">
+		<getopt mixed="-l, --username=[name]" />
+		<content type="string"  />
+		<shortdesc lang="en">Login Name</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="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="port" unique="0" required="1">
+		<getopt mixed="-n, --plug=[id]" />
+		<content type="string"  />
+		<shortdesc lang="en">Physical plug number, name of virtual machine or UUID</shortdesc>
+	</parameter>
+	<parameter name="secure" unique="0" required="0">
+		<getopt mixed="-x, --ssh" />
+		<content type="boolean"  />
+		<shortdesc lang="en">SSH connection</shortdesc>
+	</parameter>
+	<parameter name="ssh_options" unique="0" required="0">
+		<getopt mixed="--ssh-options=[options]" />
+		<content type="string" default="-1 -c blowfish"  />
+		<shortdesc lang="en">SSH options to use</shortdesc>
+	</parameter>
+	<parameter name="switch" unique="0" required="0">
+		<getopt mixed="-s, --switch=[id]" />
+		<content type="string"  />
+		<shortdesc lang="en">Physical switch number on device</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="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="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="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="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>
+	<parameter name="ssh_path" unique="0" required="0">
+		<getopt mixed="--ssh-path=[path]" />
+		<content type="string" default="/usr/bin/ssh"  />
+		<shortdesc lang="en">Path to ssh binary</shortdesc>
+	</parameter>
+	<parameter name="telnet_path" unique="0" required="0">
+		<getopt mixed="--telnet-path=[path]" />
+		<content type="string" default="/usr/bin/telnet"  />
+		<shortdesc lang="en">Path to telnet binary</shortdesc>
+	</parameter>
+</parameters>
+<actions>
+	<action name="on" automatic="0"/>
+	<action name="off" />
+	<action name="reboot" />
+	<action name="status" />
+	<action name="list" />
+	<action name="list-status" />
+	<action name="monitor" />
+	<action name="metadata" />
+	<action name="validate-all" />
+</actions>
+</resource-agent>
diff --git a/tests/data/metadata/fence_apc_snmp.xml b/tests/data/metadata/fence_apc_snmp.xml
new file mode 100644
index 0000000..71dafec
--- /dev/null
+++ b/tests/data/metadata/fence_apc_snmp.xml
@@ -0,0 +1,182 @@
+<?xml version="1.0" ?>
+<resource-agent name="fence_apc_snmp" shortdesc="Fence agent for APC, Tripplite PDU over SNMP" >
+<longdesc>fence_apc_snmp is an I/O Fencing agent which can be used with the APC network power switch or Tripplite PDU devices.It logs into a device via SNMP and reboots a specified outlet. It supports SNMP v1, v2c, v3 with all combinations of  authenticity/privacy settings.</longdesc>
+<vendor-url>http://www.apc.com</vendor-url>
+<parameters>
+	<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="community" unique="0" required="0">
+		<getopt mixed="-c, --community=[community]" />
+		<content type="string" default="private"  />
+		<shortdesc lang="en">Set the community string</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="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</shortdesc>
+	</parameter>
+	<parameter name="ipport" unique="0" required="0">
+		<getopt mixed="-u, --ipport=[port]" />
+		<content type="string" default="161"  />
+		<shortdesc lang="en">TCP/UDP port to use for connection with device</shortdesc>
+	</parameter>
+	<parameter name="login" unique="0" required="0">
+		<getopt mixed="-l, --username=[name]" />
+		<content type="string"  />
+		<shortdesc lang="en">Login Name</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="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="port" unique="0" required="1">
+		<getopt mixed="-n, --plug=[id]" />
+		<content type="string"  />
+		<shortdesc lang="en">Physical plug number, name of virtual machine or UUID</shortdesc>
+	</parameter>
+	<parameter name="snmp_auth_prot" unique="0" required="0">
+		<getopt mixed="-b, --snmp-auth-prot=[prot]" />
+		<content type="select"  >
+			<option value="MD5" />
+			<option value="SHA" />
+		</content>
+		<shortdesc lang="en">Set authentication protocol (MD5|SHA)</shortdesc>
+	</parameter>
+	<parameter name="snmp_priv_passwd" unique="0" required="0">
+		<getopt mixed="-P, --snmp-priv-passwd=[pass]" />
+		<content type="string"  />
+		<shortdesc lang="en">Set privacy protocol password</shortdesc>
+	</parameter>
+	<parameter name="snmp_priv_passwd_script" unique="0" required="0">
+		<getopt mixed="-R, --snmp-priv-passwd-script" />
+		<content type="string"  />
+		<shortdesc lang="en">Script to run to retrieve privacy password</shortdesc>
+	</parameter>
+	<parameter name="snmp_priv_prot" unique="0" required="0">
+		<getopt mixed="-B, --snmp-priv-prot=[prot]" />
+		<content type="select"  >
+			<option value="DES" />
+			<option value="AES" />
+		</content>
+		<shortdesc lang="en">Set privacy protocol (DES|AES)</shortdesc>
+	</parameter>
+	<parameter name="snmp_sec_level" unique="0" required="0">
+		<getopt mixed="-E, --snmp-sec-level=[level]" />
+		<content type="select"  >
+			<option value="noAuthNoPriv" />
+			<option value="authNoPriv" />
+			<option value="authPriv" />
+		</content>
+		<shortdesc lang="en">Set security level (noAuthNoPriv|authNoPriv|authPriv)</shortdesc>
+	</parameter>
+	<parameter name="snmp_version" unique="0" required="0">
+		<getopt mixed="-d, --snmp-version=[version]" />
+		<content type="select" default="1"  >
+			<option value="1" />
+			<option value="2c" />
+			<option value="3" />
+		</content>
+		<shortdesc lang="en">Specifies SNMP version to use (1,2c,3)</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="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="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="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="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>
+	<parameter name="snmpget_path" unique="0" required="0">
+		<getopt mixed="--snmpget-path=[path]" />
+		<content type="string" default="/usr/bin/snmpget"  />
+		<shortdesc lang="en">Path to snmpget binary</shortdesc>
+	</parameter>
+	<parameter name="snmpset_path" unique="0" required="0">
+		<getopt mixed="--snmpset-path=[path]" />
+		<content type="string" default="/usr/bin/snmpset"  />
+		<shortdesc lang="en">Path to snmpset binary</shortdesc>
+	</parameter>
+	<parameter name="snmpwalk_path" unique="0" required="0">
+		<getopt mixed="--snmpwalk-path=[path]" />
+		<content type="string" default="/usr/bin/snmpwalk"  />
+		<shortdesc lang="en">Path to snmpwalk binary</shortdesc>
+	</parameter>
+</parameters>
+<actions>
+	<action name="on" automatic="0"/>
+	<action name="off" />
+	<action name="reboot" />
+	<action name="status" />
+	<action name="list" />
+	<action name="list-status" />
+	<action name="monitor" />
+	<action name="metadata" />
+	<action name="validate-all" />
+</actions>
+</resource-agent>
diff --git a/tests/data/metadata/fence_bladecenter.xml b/tests/data/metadata/fence_bladecenter.xml
new file mode 100644
index 0000000..ac017cc
--- /dev/null
+++ b/tests/data/metadata/fence_bladecenter.xml
@@ -0,0 +1,153 @@
+<?xml version="1.0" ?>
+<resource-agent name="fence_bladecenter" shortdesc="Fence agent for IBM BladeCenter" >
+<longdesc>fence_bladecenter is an I/O Fencing agent which can be used with IBM Bladecenters with recent enough firmware that includes telnet support. It logs into a Brocade chasis via telnet or ssh and uses the command line interface to power on and off blades.</longdesc>
+<vendor-url>http://www.ibm.com</vendor-url>
+<parameters>
+	<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="cmd_prompt" unique="0" required="0">
+		<getopt mixed="-c, --command-prompt=[prompt]" />
+		<content type="string" default="['system>']"  />
+		<shortdesc lang="en">Force Python regex for command prompt</shortdesc>
+	</parameter>
+	<parameter name="identity_file" unique="0" required="0">
+		<getopt mixed="-k, --identity-file=[filename]" />
+		<content type="string"  />
+		<shortdesc lang="en">Identity file for ssh</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="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</shortdesc>
+	</parameter>
+	<parameter name="ipport" unique="0" required="0">
+		<getopt mixed="-u, --ipport=[port]" />
+		<content type="string" default="23"  />
+		<shortdesc lang="en">TCP/UDP port to use for connection with device</shortdesc>
+	</parameter>
+	<parameter name="login" unique="0" required="1">
+		<getopt mixed="-l, --username=[name]" />
+		<content type="string"  />
+		<shortdesc lang="en">Login Name</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="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="port" unique="0" required="1">
+		<getopt mixed="-n, --plug=[id]" />
+		<content type="string"  />
+		<shortdesc lang="en">Physical plug number, name of virtual machine or UUID</shortdesc>
+	</parameter>
+	<parameter name="secure" unique="0" required="0">
+		<getopt mixed="-x, --ssh" />
+		<content type="boolean"  />
+		<shortdesc lang="en">SSH connection</shortdesc>
+	</parameter>
+	<parameter name="ssh_options" unique="0" required="0">
+		<getopt mixed="--ssh-options=[options]" />
+		<content type="string"  />
+		<shortdesc lang="en">SSH options to use</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="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="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="missing_as_off" unique="0" required="0">
+		<getopt mixed="--missing-as-off" />
+		<content type="boolean"  />
+		<shortdesc lang="en">Missing port returns OFF instead of failure</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="power_wait" unique="0" required="0">
+		<getopt mixed="--power-wait=[seconds]" />
+		<content type="string" default="10"  />
+		<shortdesc lang="en">Wait X seconds after issuing ON/OFF</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>
+	<parameter name="ssh_path" unique="0" required="0">
+		<getopt mixed="--ssh-path=[path]" />
+		<content type="string" default="/usr/bin/ssh"  />
+		<shortdesc lang="en">Path to ssh binary</shortdesc>
+	</parameter>
+	<parameter name="telnet_path" unique="0" required="0">
+		<getopt mixed="--telnet-path=[path]" />
+		<content type="string" default="/usr/bin/telnet"  />
+		<shortdesc lang="en">Path to telnet binary</shortdesc>
+	</parameter>
+</parameters>
+<actions>
+	<action name="on" automatic="0"/>
+	<action name="off" />
+	<action name="reboot" />
+	<action name="status" />
+	<action name="list" />
+	<action name="list-status" />
+	<action name="monitor" />
+	<action name="metadata" />
+	<action name="validate-all" />
+</actions>
+</resource-agent>
diff --git a/tests/data/metadata/fence_brocade.xml b/tests/data/metadata/fence_brocade.xml
new file mode 100644
index 0000000..efdfe22
--- /dev/null
+++ b/tests/data/metadata/fence_brocade.xml
@@ -0,0 +1,147 @@
+<?xml version="1.0" ?>
+<resource-agent name="fence_brocade" shortdesc="Fence agent for HP Brocade over telnet/ssh" >
+<longdesc>fence_brocade is an I/O Fencing agent which can be used with Brocade FC switches. It logs into a Brocade switch via telnet and disables a specified port. Disabling the port which a machine is connected to effectively fences that machine. Lengthy telnet connections to the switch should be avoided  while a GFS cluster is running because the connection will block any necessary fencing actions. After  a fence operation has taken place the fenced machine can no longer connect to the [...]
+<vendor-url>http://www.brocade.com</vendor-url>
+<parameters>
+	<parameter name="action" unique="0" required="1">
+		<getopt mixed="-o, --action=[action]" />
+		<content type="string" default="off"  />
+		<shortdesc lang="en">Fencing Action</shortdesc>
+	</parameter>
+	<parameter name="cmd_prompt" unique="0" required="0">
+		<getopt mixed="-c, --command-prompt=[prompt]" />
+		<content type="string" default="['> ']"  />
+		<shortdesc lang="en">Force Python regex for command prompt</shortdesc>
+	</parameter>
+	<parameter name="identity_file" unique="0" required="0">
+		<getopt mixed="-k, --identity-file=[filename]" />
+		<content type="string"  />
+		<shortdesc lang="en">Identity file for ssh</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="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</shortdesc>
+	</parameter>
+	<parameter name="ipport" unique="0" required="0">
+		<getopt mixed="-u, --ipport=[port]" />
+		<content type="string" default="23"  />
+		<shortdesc lang="en">TCP/UDP port to use for connection with device</shortdesc>
+	</parameter>
+	<parameter name="login" unique="0" required="1">
+		<getopt mixed="-l, --username=[name]" />
+		<content type="string"  />
+		<shortdesc lang="en">Login Name</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="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="port" unique="0" required="1">
+		<getopt mixed="-n, --plug=[id]" />
+		<content type="string"  />
+		<shortdesc lang="en">Physical plug number, name of virtual machine or UUID</shortdesc>
+	</parameter>
+	<parameter name="secure" unique="0" required="0">
+		<getopt mixed="-x, --ssh" />
+		<content type="boolean"  />
+		<shortdesc lang="en">SSH connection</shortdesc>
+	</parameter>
+	<parameter name="ssh_options" unique="0" required="0">
+		<getopt mixed="--ssh-options=[options]" />
+		<content type="string"  />
+		<shortdesc lang="en">SSH options to use</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="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="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="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="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>
+	<parameter name="ssh_path" unique="0" required="0">
+		<getopt mixed="--ssh-path=[path]" />
+		<content type="string" default="/usr/bin/ssh"  />
+		<shortdesc lang="en">Path to ssh binary</shortdesc>
+	</parameter>
+	<parameter name="telnet_path" unique="0" required="0">
+		<getopt mixed="--telnet-path=[path]" />
+		<content type="string" default="/usr/bin/telnet"  />
+		<shortdesc lang="en">Path to telnet binary</shortdesc>
+	</parameter>
+</parameters>
+<actions>
+	<action name="on" automatic="1"/>
+	<action name="off" />
+	<action name="status" />
+	<action name="list" />
+	<action name="list-status" />
+	<action name="monitor" />
+	<action name="metadata" />
+	<action name="validate-all" />
+</actions>
+</resource-agent>
diff --git a/tests/data/metadata/fence_cisco_mds.xml b/tests/data/metadata/fence_cisco_mds.xml
new file mode 100644
index 0000000..bd07420
--- /dev/null
+++ b/tests/data/metadata/fence_cisco_mds.xml
@@ -0,0 +1,181 @@
+<?xml version="1.0" ?>
+<resource-agent name="fence_cisco_mds" shortdesc="Fence agent for Cisco MDS" >
+<longdesc>fence_cisco_mds is an I/O Fencing agent which can be used with any Cisco MDS 9000 series with SNMP enabled device.</longdesc>
+<vendor-url>http://www.cisco.com</vendor-url>
+<parameters>
+	<parameter name="action" unique="0" required="1">
+		<getopt mixed="-o, --action=[action]" />
+		<content type="string" default="off"  />
+		<shortdesc lang="en">Fencing Action</shortdesc>
+	</parameter>
+	<parameter name="community" unique="0" required="0">
+		<getopt mixed="-c, --community=[community]" />
+		<content type="string"  />
+		<shortdesc lang="en">Set the community string</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="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</shortdesc>
+	</parameter>
+	<parameter name="ipport" unique="0" required="0">
+		<getopt mixed="-u, --ipport=[port]" />
+		<content type="string" default="161"  />
+		<shortdesc lang="en">TCP/UDP port to use for connection with device</shortdesc>
+	</parameter>
+	<parameter name="login" unique="0" required="0">
+		<getopt mixed="-l, --username=[name]" />
+		<content type="string"  />
+		<shortdesc lang="en">Login Name</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="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="port" unique="0" required="1">
+		<getopt mixed="-n, --plug=[id]" />
+		<content type="string"  />
+		<shortdesc lang="en">Physical plug number, name of virtual machine or UUID</shortdesc>
+	</parameter>
+	<parameter name="snmp_auth_prot" unique="0" required="0">
+		<getopt mixed="-b, --snmp-auth-prot=[prot]" />
+		<content type="select"  >
+			<option value="MD5" />
+			<option value="SHA" />
+		</content>
+		<shortdesc lang="en">Set authentication protocol (MD5|SHA)</shortdesc>
+	</parameter>
+	<parameter name="snmp_priv_passwd" unique="0" required="0">
+		<getopt mixed="-P, --snmp-priv-passwd=[pass]" />
+		<content type="string"  />
+		<shortdesc lang="en">Set privacy protocol password</shortdesc>
+	</parameter>
+	<parameter name="snmp_priv_passwd_script" unique="0" required="0">
+		<getopt mixed="-R, --snmp-priv-passwd-script" />
+		<content type="string"  />
+		<shortdesc lang="en">Script to run to retrieve privacy password</shortdesc>
+	</parameter>
+	<parameter name="snmp_priv_prot" unique="0" required="0">
+		<getopt mixed="-B, --snmp-priv-prot=[prot]" />
+		<content type="select"  >
+			<option value="DES" />
+			<option value="AES" />
+		</content>
+		<shortdesc lang="en">Set privacy protocol (DES|AES)</shortdesc>
+	</parameter>
+	<parameter name="snmp_sec_level" unique="0" required="0">
+		<getopt mixed="-E, --snmp-sec-level=[level]" />
+		<content type="select"  >
+			<option value="noAuthNoPriv" />
+			<option value="authNoPriv" />
+			<option value="authPriv" />
+		</content>
+		<shortdesc lang="en">Set security level (noAuthNoPriv|authNoPriv|authPriv)</shortdesc>
+	</parameter>
+	<parameter name="snmp_version" unique="0" required="0">
+		<getopt mixed="-d, --snmp-version=[version]" />
+		<content type="select"  >
+			<option value="1" />
+			<option value="2c" />
+			<option value="3" />
+		</content>
+		<shortdesc lang="en">Specifies SNMP version to use (1,2c,3)</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="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="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="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="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>
+	<parameter name="snmpget_path" unique="0" required="0">
+		<getopt mixed="--snmpget-path=[path]" />
+		<content type="string" default="/usr/bin/snmpget"  />
+		<shortdesc lang="en">Path to snmpget binary</shortdesc>
+	</parameter>
+	<parameter name="snmpset_path" unique="0" required="0">
+		<getopt mixed="--snmpset-path=[path]" />
+		<content type="string" default="/usr/bin/snmpset"  />
+		<shortdesc lang="en">Path to snmpset binary</shortdesc>
+	</parameter>
+	<parameter name="snmpwalk_path" unique="0" required="0">
+		<getopt mixed="--snmpwalk-path=[path]" />
+		<content type="string" default="/usr/bin/snmpwalk"  />
+		<shortdesc lang="en">Path to snmpwalk binary</shortdesc>
+	</parameter>
+</parameters>
+<actions>
+	<action name="on" automatic="1"/>
+	<action name="off" />
+	<action name="status" />
+	<action name="list" />
+	<action name="list-status" />
+	<action name="monitor" />
+	<action name="metadata" />
+	<action name="validate-all" />
+</actions>
+</resource-agent>
diff --git a/tests/data/metadata/fence_cisco_ucs.xml b/tests/data/metadata/fence_cisco_ucs.xml
new file mode 100644
index 0000000..d4799b7
--- /dev/null
+++ b/tests/data/metadata/fence_cisco_ucs.xml
@@ -0,0 +1,148 @@
+<?xml version="1.0" ?>
+<resource-agent name="fence_cisco_ucs" shortdesc="Fence agent for Cisco UCS" >
+<longdesc>fence_cisco_ucs is an I/O Fencing agent which can be used with Cisco UCS to fence machines.</longdesc>
+<vendor-url>http://www.cisco.com</vendor-url>
+<parameters>
+	<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="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="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</shortdesc>
+	</parameter>
+	<parameter name="ipport" unique="0" required="0">
+		<getopt mixed="-u, --ipport=[port]" />
+		<content type="string" default="80"  />
+		<shortdesc lang="en">TCP/UDP port to use for connection with device</shortdesc>
+	</parameter>
+	<parameter name="login" unique="0" required="1">
+		<getopt mixed="-l, --username=[name]" />
+		<content type="string"  />
+		<shortdesc lang="en">Login Name</shortdesc>
+	</parameter>
+	<parameter name="notls" unique="0" required="0">
+		<getopt mixed="-t, --notls" />
+		<content type="boolean"  />
+		<shortdesc lang="en">Disable TLS negotiation, force SSL 3.0</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="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="port" unique="0" required="1">
+		<getopt mixed="-n, --plug=[id]" />
+		<content type="string"  />
+		<shortdesc lang="en">Physical plug number, name of virtual machine or UUID</shortdesc>
+	</parameter>
+	<parameter name="ssl" unique="0" required="0">
+		<getopt mixed="-z, --ssl" />
+		<content type="boolean"  />
+		<shortdesc lang="en">SSL connection</shortdesc>
+	</parameter>
+	<parameter name="ssl_insecure" unique="0" required="0">
+		<getopt mixed="--ssl-insecure" />
+		<content type="boolean"  />
+		<shortdesc lang="en">SSL connection without verifying fence device's certificate</shortdesc>
+	</parameter>
+	<parameter name="ssl_secure" unique="0" required="0">
+		<getopt mixed="--ssl-secure" />
+		<content type="boolean"  />
+		<shortdesc lang="en">SSL connection with verifying fence device's certificate</shortdesc>
+	</parameter>
+	<parameter name="suborg" unique="0" required="0">
+		<getopt mixed="--suborg=[path]" />
+		<content type="string" default=""  />
+		<shortdesc lang="en">Additional path needed to access suborganization</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="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="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="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="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>
+	<parameter name="gnutlscli_path" unique="0" required="0">
+		<getopt mixed="--gnutlscli-path=[path]" />
+		<content type="string" default="/usr/bin/gnutls-cli"  />
+		<shortdesc lang="en">Path to gnutls-cli binary</shortdesc>
+	</parameter>
+</parameters>
+<actions>
+	<action name="on" automatic="0"/>
+	<action name="off" />
+	<action name="reboot" />
+	<action name="status" />
+	<action name="list" />
+	<action name="list-status" />
+	<action name="monitor" />
+	<action name="metadata" />
+	<action name="validate-all" />
+</actions>
+</resource-agent>
diff --git a/tests/data/metadata/fence_docker.xml b/tests/data/metadata/fence_docker.xml
new file mode 100644
index 0000000..54d1ad3
--- /dev/null
+++ b/tests/data/metadata/fence_docker.xml
@@ -0,0 +1,146 @@
+<?xml version="1.0" ?>
+<resource-agent name="fence_docker" shortdesc="Fence agent for Docker" >
+<longdesc>fence_docker is I/O fencing agent which can be used with the Docker Engine containers. You can use this fence-agent without any authentication, or you can use TLS authentication (use --ssl option, more info about TLS authentication in docker: http://docs.docker.com/examples/https/).</longdesc>
+<vendor-url>www.docker.io</vendor-url>
+<parameters>
+	<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="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="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</shortdesc>
+	</parameter>
+	<parameter name="ipport" unique="0" required="0">
+		<getopt mixed="-u, --ipport=[port]" />
+		<content type="string" default="80"  />
+		<shortdesc lang="en">TCP/UDP port to use for connection with device</shortdesc>
+	</parameter>
+	<parameter name="method" unique="0" required="0">
+		<getopt mixed="-m, --method=[method]" />
+		<content type="select" default="onoff"  >
+			<option value="onoff" />
+			<option value="cycle" />
+		</content>
+		<shortdesc lang="en">Method to fence (onoff|cycle)</shortdesc>
+	</parameter>
+	<parameter name="port" unique="0" required="1">
+		<getopt mixed="-n, --plug=[id]" />
+		<content type="string"  />
+		<shortdesc lang="en">Physical plug number, name of virtual machine or UUID</shortdesc>
+	</parameter>
+	<parameter name="ssl" unique="0" required="0">
+		<getopt mixed="-z, --ssl" />
+		<content type="boolean"  />
+		<shortdesc lang="en">SSL connection</shortdesc>
+	</parameter>
+	<parameter name="ssl_insecure" unique="0" required="0">
+		<getopt mixed="--ssl-insecure" />
+		<content type="boolean"  />
+		<shortdesc lang="en">SSL connection without verifying fence device's certificate</shortdesc>
+	</parameter>
+	<parameter name="ssl_secure" unique="0" required="0">
+		<getopt mixed="--ssl-secure" />
+		<content type="boolean"  />
+		<shortdesc lang="en">SSL connection with verifying fence device's certificate</shortdesc>
+	</parameter>
+	<parameter name="tlscacert" unique="0" required="0">
+		<getopt mixed="--tlscacert" />
+		<content type="string"  />
+		<shortdesc lang="en">Path to CA certificate (PEM format) for TLS authentication.  Required if --ssl option is used.</shortdesc>
+	</parameter>
+	<parameter name="tlscert" unique="0" required="0">
+		<getopt mixed="--tlscert" />
+		<content type="string"  />
+		<shortdesc lang="en">Path to client certificate (PEM format) for TLS authentication. Required if --ssl option is used.</shortdesc>
+	</parameter>
+	<parameter name="tlskey" unique="0" required="0">
+		<getopt mixed="--tlskey" />
+		<content type="string"  />
+		<shortdesc lang="en">Path to client key (PEM format) for TLS authentication.  Required if --ssl option is used.</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="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="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="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="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>
+	<parameter name="gnutlscli_path" unique="0" required="0">
+		<getopt mixed="--gnutlscli-path=[path]" />
+		<content type="string" default="/usr/bin/gnutls-cli"  />
+		<shortdesc lang="en">Path to gnutls-cli binary</shortdesc>
+	</parameter>
+</parameters>
+<actions>
+	<action name="on" automatic="0"/>
+	<action name="off" />
+	<action name="reboot" />
+	<action name="status" />
+	<action name="list" />
+	<action name="list-status" />
+	<action name="monitor" />
+	<action name="metadata" />
+	<action name="validate-all" />
+</actions>
+</resource-agent>
diff --git a/tests/data/metadata/fence_drac.xml b/tests/data/metadata/fence_drac.xml
new file mode 100644
index 0000000..6d3c934
--- /dev/null
+++ b/tests/data/metadata/fence_drac.xml
@@ -0,0 +1,116 @@
+<?xml version="1.0" ?>
+<resource-agent name="fence_drac" shortdesc="I/O Fencing agent for Dell DRAC IV" >
+<longdesc>fence_drac is an I/O Fencing agent which can be used with the Dell Remote Access Card (DRAC). This card provides remote access to controlling power to a server. It logs into the DRAC through the telnet interface of the card. By default, the telnet interface is not enabled. To enable the interface, you will need to use the racadm command in the racser-devel rpm available from Dell.  To enable telnet on the DRAC: [root]# racadm config -g cfgSerial -o cfgSerialTelnetEnable 1 [root [...]
+<vendor-url>http://www.dell.com</vendor-url>
+<parameters>
+	<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="cmd_prompt" unique="0" required="0">
+		<getopt mixed="-c, --command-prompt=[prompt]" />
+		<content type="string" default="['\\[username\\]# ']"  />
+		<shortdesc lang="en">Force Python regex for command prompt</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="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</shortdesc>
+	</parameter>
+	<parameter name="ipport" unique="0" required="0">
+		<getopt mixed="-u, --ipport=[port]" />
+		<content type="string" default="23"  />
+		<shortdesc lang="en">TCP/UDP port to use for connection with device</shortdesc>
+	</parameter>
+	<parameter name="login" unique="0" required="1">
+		<getopt mixed="-l, --username=[name]" />
+		<content type="string"  />
+		<shortdesc lang="en">Login Name</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="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="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="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="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="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="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>
+	<parameter name="telnet_path" unique="0" required="0">
+		<getopt mixed="--telnet-path=[path]" />
+		<content type="string" default="/usr/bin/telnet"  />
+		<shortdesc lang="en">Path to telnet binary</shortdesc>
+	</parameter>
+</parameters>
+<actions>
+	<action name="on" automatic="0"/>
+	<action name="off" />
+	<action name="reboot" />
+	<action name="status" />
+	<action name="monitor" />
+	<action name="metadata" />
+	<action name="validate-all" />
+</actions>
+</resource-agent>
diff --git a/tests/data/metadata/fence_drac5.xml b/tests/data/metadata/fence_drac5.xml
new file mode 100644
index 0000000..39e85e8
--- /dev/null
+++ b/tests/data/metadata/fence_drac5.xml
@@ -0,0 +1,157 @@
+<?xml version="1.0" ?>
+<resource-agent name="fence_drac5" shortdesc="Fence agent for Dell DRAC CMC/5" >
+<longdesc>fence_drac5 is an I/O Fencing agent which can be used with the Dell Remote Access Card v5 or CMC (DRAC). This device provides remote access to controlling  power to a server. It logs into the DRAC through the telnet/ssh interface of the card. By default, the telnet interface is not  enabled.</longdesc>
+<vendor-url>http://www.dell.com</vendor-url>
+<parameters>
+	<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="cmd_prompt" unique="0" required="0">
+		<getopt mixed="-c, --command-prompt=[prompt]" />
+		<content type="string" default="['\\$', 'DRAC\\/MC:']"  />
+		<shortdesc lang="en">Force Python regex for command prompt</shortdesc>
+	</parameter>
+	<parameter name="drac_version" unique="0" required="0">
+		<getopt mixed="-d, --drac-version=[version]" />
+		<content type="select"  >
+			<option value="DRAC CMC" />
+			<option value="DRAC MC" />
+			<option value="DRAC 5" />
+		</content>
+		<shortdesc lang="en">Force DRAC version to use (DRAC 5, DRAC CMC, DRAC MC)</shortdesc>
+	</parameter>
+	<parameter name="identity_file" unique="0" required="0">
+		<getopt mixed="-k, --identity-file=[filename]" />
+		<content type="string"  />
+		<shortdesc lang="en">Identity file for ssh</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="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</shortdesc>
+	</parameter>
+	<parameter name="ipport" unique="0" required="0">
+		<getopt mixed="-u, --ipport=[port]" />
+		<content type="string" default="23"  />
+		<shortdesc lang="en">TCP/UDP port to use for connection with device</shortdesc>
+	</parameter>
+	<parameter name="login" unique="0" required="1">
+		<getopt mixed="-l, --username=[name]" />
+		<content type="string"  />
+		<shortdesc lang="en">Login Name</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="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="port" unique="0" required="1">
+		<getopt mixed="-n, --plug=[id]" />
+		<content type="string"  />
+		<shortdesc lang="en">Physical plug number, name of virtual machine or UUID</shortdesc>
+	</parameter>
+	<parameter name="secure" unique="0" required="0">
+		<getopt mixed="-x, --ssh" />
+		<content type="boolean"  />
+		<shortdesc lang="en">SSH connection</shortdesc>
+	</parameter>
+	<parameter name="ssh_options" unique="0" required="0">
+		<getopt mixed="--ssh-options=[options]" />
+		<content type="string"  />
+		<shortdesc lang="en">SSH options to use</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="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="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="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="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>
+	<parameter name="ssh_path" unique="0" required="0">
+		<getopt mixed="--ssh-path=[path]" />
+		<content type="string" default="/usr/bin/ssh"  />
+		<shortdesc lang="en">Path to ssh binary</shortdesc>
+	</parameter>
+	<parameter name="telnet_path" unique="0" required="0">
+		<getopt mixed="--telnet-path=[path]" />
+		<content type="string" default="/usr/bin/telnet"  />
+		<shortdesc lang="en">Path to telnet binary</shortdesc>
+	</parameter>
+</parameters>
+<actions>
+	<action name="on" automatic="0"/>
+	<action name="off" />
+	<action name="reboot" />
+	<action name="status" />
+	<action name="list" />
+	<action name="list-status" />
+	<action name="monitor" />
+	<action name="metadata" />
+	<action name="validate-all" />
+</actions>
+</resource-agent>
diff --git a/tests/data/metadata/fence_dummy.xml b/tests/data/metadata/fence_dummy.xml
new file mode 100644
index 0000000..8405473
--- /dev/null
+++ b/tests/data/metadata/fence_dummy.xml
@@ -0,0 +1,93 @@
+<?xml version="1.0" ?>
+<resource-agent name="fence_dummy" shortdesc="Dummy fence agent" >
+<longdesc>fence_dummy</longdesc>
+<vendor-url>http://www.example.com</vendor-url>
+<parameters>
+	<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="random_sleep_range" unique="0" required="0">
+		<getopt mixed="--random_sleep_range=[seconds]" />
+		<content type="string"  />
+		<shortdesc lang="en">Issue a sleep between 1 and X seconds. Used for testing.</shortdesc>
+	</parameter>
+	<parameter name="status_file" unique="0" required="0">
+		<getopt mixed="--status-file=[file]" />
+		<content type="string" default="/tmp/fence_dummy.status"  />
+		<shortdesc lang="en">File with status</shortdesc>
+	</parameter>
+	<parameter name="type" unique="0" required="0">
+		<getopt mixed="--type=[type]" />
+		<content type="string" default="file"  />
+		<shortdesc lang="en">Type of the dummy fence agent</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="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="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="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="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="list-status" />
+	<action name="monitor" />
+	<action name="metadata" />
+	<action name="validate-all" />
+</actions>
+</resource-agent>
diff --git a/tests/data/metadata/fence_eaton_snmp.xml b/tests/data/metadata/fence_eaton_snmp.xml
new file mode 100644
index 0000000..660c1b6
--- /dev/null
+++ b/tests/data/metadata/fence_eaton_snmp.xml
@@ -0,0 +1,182 @@
+<?xml version="1.0" ?>
+<resource-agent name="fence_eaton_snmp" shortdesc="Fence agent for Eaton over SNMP" >
+<longdesc>fence_eaton_snmp is an I/O Fencing agent which can be used with the Eaton network power switch. It logs into a device via SNMP and reboots a specified outlet. It supports SNMP v1 and v3 with all combinations of  authenticity/privacy settings.</longdesc>
+<vendor-url>http://powerquality.eaton.com</vendor-url>
+<parameters>
+	<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="community" unique="0" required="0">
+		<getopt mixed="-c, --community=[community]" />
+		<content type="string" default="private"  />
+		<shortdesc lang="en">Set the community string</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="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</shortdesc>
+	</parameter>
+	<parameter name="ipport" unique="0" required="0">
+		<getopt mixed="-u, --ipport=[port]" />
+		<content type="string" default="161"  />
+		<shortdesc lang="en">TCP/UDP port to use for connection with device</shortdesc>
+	</parameter>
+	<parameter name="login" unique="0" required="0">
+		<getopt mixed="-l, --username=[name]" />
+		<content type="string"  />
+		<shortdesc lang="en">Login Name</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="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="port" unique="0" required="1">
+		<getopt mixed="-n, --plug=[id]" />
+		<content type="string"  />
+		<shortdesc lang="en">Physical plug number, name of virtual machine or UUID</shortdesc>
+	</parameter>
+	<parameter name="snmp_auth_prot" unique="0" required="0">
+		<getopt mixed="-b, --snmp-auth-prot=[prot]" />
+		<content type="select"  >
+			<option value="MD5" />
+			<option value="SHA" />
+		</content>
+		<shortdesc lang="en">Set authentication protocol (MD5|SHA)</shortdesc>
+	</parameter>
+	<parameter name="snmp_priv_passwd" unique="0" required="0">
+		<getopt mixed="-P, --snmp-priv-passwd=[pass]" />
+		<content type="string"  />
+		<shortdesc lang="en">Set privacy protocol password</shortdesc>
+	</parameter>
+	<parameter name="snmp_priv_passwd_script" unique="0" required="0">
+		<getopt mixed="-R, --snmp-priv-passwd-script" />
+		<content type="string"  />
+		<shortdesc lang="en">Script to run to retrieve privacy password</shortdesc>
+	</parameter>
+	<parameter name="snmp_priv_prot" unique="0" required="0">
+		<getopt mixed="-B, --snmp-priv-prot=[prot]" />
+		<content type="select"  >
+			<option value="DES" />
+			<option value="AES" />
+		</content>
+		<shortdesc lang="en">Set privacy protocol (DES|AES)</shortdesc>
+	</parameter>
+	<parameter name="snmp_sec_level" unique="0" required="0">
+		<getopt mixed="-E, --snmp-sec-level=[level]" />
+		<content type="select"  >
+			<option value="noAuthNoPriv" />
+			<option value="authNoPriv" />
+			<option value="authPriv" />
+		</content>
+		<shortdesc lang="en">Set security level (noAuthNoPriv|authNoPriv|authPriv)</shortdesc>
+	</parameter>
+	<parameter name="snmp_version" unique="0" required="0">
+		<getopt mixed="-d, --snmp-version=[version]" />
+		<content type="select" default="1"  >
+			<option value="1" />
+			<option value="2c" />
+			<option value="3" />
+		</content>
+		<shortdesc lang="en">Specifies SNMP version to use (1,2c,3)</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="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="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="power_wait" unique="0" required="0">
+		<getopt mixed="--power-wait=[seconds]" />
+		<content type="string" default="2"  />
+		<shortdesc lang="en">Wait X seconds after issuing ON/OFF</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>
+	<parameter name="snmpget_path" unique="0" required="0">
+		<getopt mixed="--snmpget-path=[path]" />
+		<content type="string" default="/usr/bin/snmpget"  />
+		<shortdesc lang="en">Path to snmpget binary</shortdesc>
+	</parameter>
+	<parameter name="snmpset_path" unique="0" required="0">
+		<getopt mixed="--snmpset-path=[path]" />
+		<content type="string" default="/usr/bin/snmpset"  />
+		<shortdesc lang="en">Path to snmpset binary</shortdesc>
+	</parameter>
+	<parameter name="snmpwalk_path" unique="0" required="0">
+		<getopt mixed="--snmpwalk-path=[path]" />
+		<content type="string" default="/usr/bin/snmpwalk"  />
+		<shortdesc lang="en">Path to snmpwalk binary</shortdesc>
+	</parameter>
+</parameters>
+<actions>
+	<action name="on" automatic="0"/>
+	<action name="off" />
+	<action name="reboot" />
+	<action name="status" />
+	<action name="list" />
+	<action name="list-status" />
+	<action name="monitor" />
+	<action name="metadata" />
+	<action name="validate-all" />
+</actions>
+</resource-agent>
diff --git a/tests/data/metadata/fence_emerson.xml b/tests/data/metadata/fence_emerson.xml
new file mode 100644
index 0000000..7eadd41
--- /dev/null
+++ b/tests/data/metadata/fence_emerson.xml
@@ -0,0 +1,182 @@
+<?xml version="1.0" ?>
+<resource-agent name="fence_emerson" shortdesc="Fence agent for Emerson over SNMP" >
+<longdesc>fence_emerson is an I/O Fencing agent 	which can be used with MPX and MPH2 managed rack PDU.</longdesc>
+<vendor-url>http://www.emersonnetworkpower.com</vendor-url>
+<parameters>
+	<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="community" unique="0" required="0">
+		<getopt mixed="-c, --community=[community]" />
+		<content type="string"  />
+		<shortdesc lang="en">Set the community string</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="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</shortdesc>
+	</parameter>
+	<parameter name="ipport" unique="0" required="0">
+		<getopt mixed="-u, --ipport=[port]" />
+		<content type="string" default="161"  />
+		<shortdesc lang="en">TCP/UDP port to use for connection with device</shortdesc>
+	</parameter>
+	<parameter name="login" unique="0" required="0">
+		<getopt mixed="-l, --username=[name]" />
+		<content type="string"  />
+		<shortdesc lang="en">Login Name</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="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="port" unique="0" required="1">
+		<getopt mixed="-n, --plug=[id]" />
+		<content type="string"  />
+		<shortdesc lang="en">Physical plug number, name of virtual machine or UUID</shortdesc>
+	</parameter>
+	<parameter name="snmp_auth_prot" unique="0" required="0">
+		<getopt mixed="-b, --snmp-auth-prot=[prot]" />
+		<content type="select"  >
+			<option value="MD5" />
+			<option value="SHA" />
+		</content>
+		<shortdesc lang="en">Set authentication protocol (MD5|SHA)</shortdesc>
+	</parameter>
+	<parameter name="snmp_priv_passwd" unique="0" required="0">
+		<getopt mixed="-P, --snmp-priv-passwd=[pass]" />
+		<content type="string"  />
+		<shortdesc lang="en">Set privacy protocol password</shortdesc>
+	</parameter>
+	<parameter name="snmp_priv_passwd_script" unique="0" required="0">
+		<getopt mixed="-R, --snmp-priv-passwd-script" />
+		<content type="string"  />
+		<shortdesc lang="en">Script to run to retrieve privacy password</shortdesc>
+	</parameter>
+	<parameter name="snmp_priv_prot" unique="0" required="0">
+		<getopt mixed="-B, --snmp-priv-prot=[prot]" />
+		<content type="select"  >
+			<option value="DES" />
+			<option value="AES" />
+		</content>
+		<shortdesc lang="en">Set privacy protocol (DES|AES)</shortdesc>
+	</parameter>
+	<parameter name="snmp_sec_level" unique="0" required="0">
+		<getopt mixed="-E, --snmp-sec-level=[level]" />
+		<content type="select"  >
+			<option value="noAuthNoPriv" />
+			<option value="authNoPriv" />
+			<option value="authPriv" />
+		</content>
+		<shortdesc lang="en">Set security level (noAuthNoPriv|authNoPriv|authPriv)</shortdesc>
+	</parameter>
+	<parameter name="snmp_version" unique="0" required="0">
+		<getopt mixed="-d, --snmp-version=[version]" />
+		<content type="select"  >
+			<option value="1" />
+			<option value="2c" />
+			<option value="3" />
+		</content>
+		<shortdesc lang="en">Specifies SNMP version to use (1,2c,3)</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="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="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="power_wait" unique="0" required="0">
+		<getopt mixed="--power-wait=[seconds]" />
+		<content type="string" default="5"  />
+		<shortdesc lang="en">Wait X seconds after issuing ON/OFF</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>
+	<parameter name="snmpget_path" unique="0" required="0">
+		<getopt mixed="--snmpget-path=[path]" />
+		<content type="string" default="/usr/bin/snmpget"  />
+		<shortdesc lang="en">Path to snmpget binary</shortdesc>
+	</parameter>
+	<parameter name="snmpset_path" unique="0" required="0">
+		<getopt mixed="--snmpset-path=[path]" />
+		<content type="string" default="/usr/bin/snmpset"  />
+		<shortdesc lang="en">Path to snmpset binary</shortdesc>
+	</parameter>
+	<parameter name="snmpwalk_path" unique="0" required="0">
+		<getopt mixed="--snmpwalk-path=[path]" />
+		<content type="string" default="/usr/bin/snmpwalk"  />
+		<shortdesc lang="en">Path to snmpwalk binary</shortdesc>
+	</parameter>
+</parameters>
+<actions>
+	<action name="on" automatic="0"/>
+	<action name="off" />
+	<action name="reboot" />
+	<action name="status" />
+	<action name="list" />
+	<action name="list-status" />
+	<action name="monitor" />
+	<action name="metadata" />
+	<action name="validate-all" />
+</actions>
+</resource-agent>
diff --git a/tests/data/metadata/fence_eps.xml b/tests/data/metadata/fence_eps.xml
new file mode 100644
index 0000000..f9f7f8a
--- /dev/null
+++ b/tests/data/metadata/fence_eps.xml
@@ -0,0 +1,125 @@
+<?xml version="1.0" ?>
+<resource-agent name="fence_eps" shortdesc="Fence agent for ePowerSwitch" >
+<longdesc>fence_eps  is an I/O Fencing agent which can be used with the ePowerSwitch 8M+ power switch to fence connected machines. Fence agent works ONLY on 8M+ device, because this is only one, which has support for hidden page feature. 
+.TP
+Agent basically works by connecting to hidden page and pass appropriate arguments to GET request. This means, that hidden page feature must be enabled and properly configured.</longdesc>
+<vendor-url>http://www.epowerswitch.com</vendor-url>
+<parameters>
+	<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="hidden_page" unique="0" required="0">
+		<getopt mixed="-c, --page=[page]" />
+		<content type="string" default="hidden.htm"  />
+		<shortdesc lang="en">Name of hidden page</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="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</shortdesc>
+	</parameter>
+	<parameter name="ipport" unique="0" required="0">
+		<getopt mixed="-u, --ipport=[port]" />
+		<content type="string" default="80"  />
+		<shortdesc lang="en">TCP/UDP port to use for connection with device</shortdesc>
+	</parameter>
+	<parameter name="login" unique="0" required="0">
+		<getopt mixed="-l, --username=[name]" />
+		<content type="string"  />
+		<shortdesc lang="en">Login Name</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="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="port" unique="0" required="1">
+		<getopt mixed="-n, --plug=[id]" />
+		<content type="string"  />
+		<shortdesc lang="en">Physical plug number, name of virtual machine or UUID</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="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="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="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="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="list-status" />
+	<action name="monitor" />
+	<action name="metadata" />
+	<action name="validate-all" />
+</actions>
+</resource-agent>
diff --git a/tests/data/metadata/fence_hds_cb.xml b/tests/data/metadata/fence_hds_cb.xml
new file mode 100644
index 0000000..75bb81d
--- /dev/null
+++ b/tests/data/metadata/fence_hds_cb.xml
@@ -0,0 +1,153 @@
+<?xml version="1.0" ?>
+<resource-agent name="fence_hds_cb" shortdesc="Fence agent for Hitachi Compute Blade systems" >
+<longdesc>fence_hds_cb is an I/O Fencing agent which can be used with Hitachi Compute Blades with recent enough firmware that includes telnet support.</longdesc>
+<vendor-url>http://www.hds.com</vendor-url>
+<parameters>
+	<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="cmd_prompt" unique="0" required="0">
+		<getopt mixed="-c, --command-prompt=[prompt]" />
+		<content type="string" default="['\\) :']"  />
+		<shortdesc lang="en">Force Python regex for command prompt</shortdesc>
+	</parameter>
+	<parameter name="identity_file" unique="0" required="0">
+		<getopt mixed="-k, --identity-file=[filename]" />
+		<content type="string"  />
+		<shortdesc lang="en">Identity file for ssh</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="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</shortdesc>
+	</parameter>
+	<parameter name="ipport" unique="0" required="0">
+		<getopt mixed="-u, --ipport=[port]" />
+		<content type="string" default="23"  />
+		<shortdesc lang="en">TCP/UDP port to use for connection with device</shortdesc>
+	</parameter>
+	<parameter name="login" unique="0" required="1">
+		<getopt mixed="-l, --username=[name]" />
+		<content type="string"  />
+		<shortdesc lang="en">Login Name</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="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="port" unique="0" required="1">
+		<getopt mixed="-n, --plug=[id]" />
+		<content type="string"  />
+		<shortdesc lang="en">Physical plug number, name of virtual machine or UUID</shortdesc>
+	</parameter>
+	<parameter name="secure" unique="0" required="0">
+		<getopt mixed="-x, --ssh" />
+		<content type="boolean"  />
+		<shortdesc lang="en">SSH connection</shortdesc>
+	</parameter>
+	<parameter name="ssh_options" unique="0" required="0">
+		<getopt mixed="--ssh-options=[options]" />
+		<content type="string"  />
+		<shortdesc lang="en">SSH options to use</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="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="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="missing_as_off" unique="0" required="0">
+		<getopt mixed="--missing-as-off" />
+		<content type="boolean"  />
+		<shortdesc lang="en">Missing port returns OFF instead of failure</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="power_wait" unique="0" required="0">
+		<getopt mixed="--power-wait=[seconds]" />
+		<content type="string" default="5"  />
+		<shortdesc lang="en">Wait X seconds after issuing ON/OFF</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>
+	<parameter name="ssh_path" unique="0" required="0">
+		<getopt mixed="--ssh-path=[path]" />
+		<content type="string" default="/usr/bin/ssh"  />
+		<shortdesc lang="en">Path to ssh binary</shortdesc>
+	</parameter>
+	<parameter name="telnet_path" unique="0" required="0">
+		<getopt mixed="--telnet-path=[path]" />
+		<content type="string" default="/usr/bin/telnet"  />
+		<shortdesc lang="en">Path to telnet binary</shortdesc>
+	</parameter>
+</parameters>
+<actions>
+	<action name="on" automatic="0"/>
+	<action name="off" />
+	<action name="reboot" />
+	<action name="status" />
+	<action name="list" />
+	<action name="list-status" />
+	<action name="monitor" />
+	<action name="metadata" />
+	<action name="validate-all" />
+</actions>
+</resource-agent>
diff --git a/tests/data/metadata/fence_hpblade.xml b/tests/data/metadata/fence_hpblade.xml
new file mode 100644
index 0000000..380a185
--- /dev/null
+++ b/tests/data/metadata/fence_hpblade.xml
@@ -0,0 +1,153 @@
+<?xml version="1.0" ?>
+<resource-agent name="fence_hpblade" shortdesc="Fence agent for HP BladeSystem" >
+<longdesc>fence_hpblade is an I/O Fencing agent which can be used with HP BladeSystem. It logs into an enclosure via telnet or ssh and uses the command line interface to power on and off blades.</longdesc>
+<vendor-url>http://www.hp.com</vendor-url>
+<parameters>
+	<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="cmd_prompt" unique="0" required="0">
+		<getopt mixed="-c, --command-prompt=[prompt]" />
+		<content type="string" default="['c7000oa>']"  />
+		<shortdesc lang="en">Force Python regex for command prompt</shortdesc>
+	</parameter>
+	<parameter name="identity_file" unique="0" required="0">
+		<getopt mixed="-k, --identity-file=[filename]" />
+		<content type="string"  />
+		<shortdesc lang="en">Identity file for ssh</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="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</shortdesc>
+	</parameter>
+	<parameter name="ipport" unique="0" required="0">
+		<getopt mixed="-u, --ipport=[port]" />
+		<content type="string" default="23"  />
+		<shortdesc lang="en">TCP/UDP port to use for connection with device</shortdesc>
+	</parameter>
+	<parameter name="login" unique="0" required="1">
+		<getopt mixed="-l, --username=[name]" />
+		<content type="string"  />
+		<shortdesc lang="en">Login Name</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="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="port" unique="0" required="1">
+		<getopt mixed="-n, --plug=[id]" />
+		<content type="string"  />
+		<shortdesc lang="en">Physical plug number, name of virtual machine or UUID</shortdesc>
+	</parameter>
+	<parameter name="secure" unique="0" required="0">
+		<getopt mixed="-x, --ssh" />
+		<content type="boolean"  />
+		<shortdesc lang="en">SSH connection</shortdesc>
+	</parameter>
+	<parameter name="ssh_options" unique="0" required="0">
+		<getopt mixed="--ssh-options=[options]" />
+		<content type="string"  />
+		<shortdesc lang="en">SSH options to use</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="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="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="missing_as_off" unique="0" required="0">
+		<getopt mixed="--missing-as-off" />
+		<content type="boolean"  />
+		<shortdesc lang="en">Missing port returns OFF instead of failure</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="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="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>
+	<parameter name="ssh_path" unique="0" required="0">
+		<getopt mixed="--ssh-path=[path]" />
+		<content type="string" default="/usr/bin/ssh"  />
+		<shortdesc lang="en">Path to ssh binary</shortdesc>
+	</parameter>
+	<parameter name="telnet_path" unique="0" required="0">
+		<getopt mixed="--telnet-path=[path]" />
+		<content type="string" default="/usr/bin/telnet"  />
+		<shortdesc lang="en">Path to telnet binary</shortdesc>
+	</parameter>
+</parameters>
+<actions>
+	<action name="on" automatic="0"/>
+	<action name="off" />
+	<action name="reboot" />
+	<action name="status" />
+	<action name="list" />
+	<action name="list-status" />
+	<action name="monitor" />
+	<action name="metadata" />
+	<action name="validate-all" />
+</actions>
+</resource-agent>
diff --git a/tests/data/metadata/fence_ibmblade.xml b/tests/data/metadata/fence_ibmblade.xml
new file mode 100644
index 0000000..d0492b8
--- /dev/null
+++ b/tests/data/metadata/fence_ibmblade.xml
@@ -0,0 +1,182 @@
+<?xml version="1.0" ?>
+<resource-agent name="fence_ibmblade" shortdesc="Fence agent for IBM BladeCenter over SNMP" >
+<longdesc>fence_ibmblade is an I/O Fencing agent which can be used with IBM BladeCenter chassis. It issues SNMP Set request to BladeCenter chassis, rebooting, powering up or down the specified Blade Server.</longdesc>
+<vendor-url>http://www.ibm.com</vendor-url>
+<parameters>
+	<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="community" unique="0" required="0">
+		<getopt mixed="-c, --community=[community]" />
+		<content type="string"  />
+		<shortdesc lang="en">Set the community string</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="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</shortdesc>
+	</parameter>
+	<parameter name="ipport" unique="0" required="0">
+		<getopt mixed="-u, --ipport=[port]" />
+		<content type="string" default="161"  />
+		<shortdesc lang="en">TCP/UDP port to use for connection with device</shortdesc>
+	</parameter>
+	<parameter name="login" unique="0" required="0">
+		<getopt mixed="-l, --username=[name]" />
+		<content type="string"  />
+		<shortdesc lang="en">Login Name</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="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="port" unique="0" required="1">
+		<getopt mixed="-n, --plug=[id]" />
+		<content type="string"  />
+		<shortdesc lang="en">Physical plug number, name of virtual machine or UUID</shortdesc>
+	</parameter>
+	<parameter name="snmp_auth_prot" unique="0" required="0">
+		<getopt mixed="-b, --snmp-auth-prot=[prot]" />
+		<content type="select"  >
+			<option value="MD5" />
+			<option value="SHA" />
+		</content>
+		<shortdesc lang="en">Set authentication protocol (MD5|SHA)</shortdesc>
+	</parameter>
+	<parameter name="snmp_priv_passwd" unique="0" required="0">
+		<getopt mixed="-P, --snmp-priv-passwd=[pass]" />
+		<content type="string"  />
+		<shortdesc lang="en">Set privacy protocol password</shortdesc>
+	</parameter>
+	<parameter name="snmp_priv_passwd_script" unique="0" required="0">
+		<getopt mixed="-R, --snmp-priv-passwd-script" />
+		<content type="string"  />
+		<shortdesc lang="en">Script to run to retrieve privacy password</shortdesc>
+	</parameter>
+	<parameter name="snmp_priv_prot" unique="0" required="0">
+		<getopt mixed="-B, --snmp-priv-prot=[prot]" />
+		<content type="select"  >
+			<option value="DES" />
+			<option value="AES" />
+		</content>
+		<shortdesc lang="en">Set privacy protocol (DES|AES)</shortdesc>
+	</parameter>
+	<parameter name="snmp_sec_level" unique="0" required="0">
+		<getopt mixed="-E, --snmp-sec-level=[level]" />
+		<content type="select"  >
+			<option value="noAuthNoPriv" />
+			<option value="authNoPriv" />
+			<option value="authPriv" />
+		</content>
+		<shortdesc lang="en">Set security level (noAuthNoPriv|authNoPriv|authPriv)</shortdesc>
+	</parameter>
+	<parameter name="snmp_version" unique="0" required="0">
+		<getopt mixed="-d, --snmp-version=[version]" />
+		<content type="select" default="1"  >
+			<option value="1" />
+			<option value="2c" />
+			<option value="3" />
+		</content>
+		<shortdesc lang="en">Specifies SNMP version to use (1,2c,3)</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="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="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="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="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>
+	<parameter name="snmpget_path" unique="0" required="0">
+		<getopt mixed="--snmpget-path=[path]" />
+		<content type="string" default="/usr/bin/snmpget"  />
+		<shortdesc lang="en">Path to snmpget binary</shortdesc>
+	</parameter>
+	<parameter name="snmpset_path" unique="0" required="0">
+		<getopt mixed="--snmpset-path=[path]" />
+		<content type="string" default="/usr/bin/snmpset"  />
+		<shortdesc lang="en">Path to snmpset binary</shortdesc>
+	</parameter>
+	<parameter name="snmpwalk_path" unique="0" required="0">
+		<getopt mixed="--snmpwalk-path=[path]" />
+		<content type="string" default="/usr/bin/snmpwalk"  />
+		<shortdesc lang="en">Path to snmpwalk binary</shortdesc>
+	</parameter>
+</parameters>
+<actions>
+	<action name="on" automatic="0"/>
+	<action name="off" />
+	<action name="reboot" />
+	<action name="status" />
+	<action name="list" />
+	<action name="list-status" />
+	<action name="monitor" />
+	<action name="metadata" />
+	<action name="validate-all" />
+</actions>
+</resource-agent>
diff --git a/tests/data/metadata/fence_idrac.xml b/tests/data/metadata/fence_idrac.xml
new file mode 100644
index 0000000..fc2aa74
--- /dev/null
+++ b/tests/data/metadata/fence_idrac.xml
@@ -0,0 +1,162 @@
+<?xml version="1.0" ?>
+<resource-agent name="fence_idrac" shortdesc="Fence agent for IPMI" >
+<symlink name="fence_ilo3" shortdesc="Fence agent for HP iLO3"/>
+<symlink name="fence_ilo4" shortdesc="Fence agent for HP iLO4"/>
+<symlink name="fence_imm" shortdesc="Fence agent for IBM Integrated Management Module"/>
+<symlink name="fence_idrac" shortdesc="Fence agent for Dell iDRAC"/>
+<longdesc>fence_ipmilan is an I/O Fencing agentwhich can be used with machines controlled by IPMI.This agent calls support software ipmitool (http://ipmitool.sf.net/).</longdesc>
+<vendor-url></vendor-url>
+<parameters>
+	<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="auth" unique="0" required="0">
+		<getopt mixed="-A, --auth=[auth]" />
+		<content type="select"  >
+			<option value="md5" />
+			<option value="password" />
+			<option value="none" />
+		</content>
+		<shortdesc lang="en">IPMI Lan Auth type.</shortdesc>
+	</parameter>
+	<parameter name="cipher" unique="0" required="0">
+		<getopt mixed="-C, --cipher=[cipher]" />
+		<content type="string"  />
+		<shortdesc lang="en">Ciphersuite to use (same as ipmitool -C parameter)</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="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</shortdesc>
+	</parameter>
+	<parameter name="ipport" unique="0" required="0">
+		<getopt mixed="-u, --ipport=[port]" />
+		<content type="string" default="623"  />
+		<shortdesc lang="en">TCP/UDP port to use for connection with device</shortdesc>
+	</parameter>
+	<parameter name="lanplus" unique="0" required="0">
+		<getopt mixed="-P, --lanplus" />
+		<content type="boolean" default="0"  />
+		<shortdesc lang="en">Use Lanplus to improve security of connection</shortdesc>
+	</parameter>
+	<parameter name="login" unique="0" required="0">
+		<getopt mixed="-l, --username=[name]" />
+		<content type="string"  />
+		<shortdesc lang="en">Login Name</shortdesc>
+	</parameter>
+	<parameter name="method" unique="0" required="0">
+		<getopt mixed="-m, --method=[method]" />
+		<content type="select" default="onoff"  >
+			<option value="onoff" />
+			<option value="cycle" />
+		</content>
+		<shortdesc lang="en">Method to fence (onoff|cycle)</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="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="privlvl" unique="0" required="0">
+		<getopt mixed="-L, --privlvl=[level]" />
+		<content type="select" default="administrator"  >
+			<option value="callback" />
+			<option value="user" />
+			<option value="operator" />
+			<option value="administrator" />
+		</content>
+		<shortdesc lang="en">Privilege level on IPMI device</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="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="ipmitool_path" unique="0" required="0">
+		<getopt mixed="--ipmitool-path=[path]" />
+		<content type="string" default="/usr/bin/ipmitool"  />
+		<shortdesc lang="en">Path to ipmitool binary</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="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="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>
+	<parameter name="sudo" unique="0" required="0">
+		<getopt mixed="--use-sudo" />
+		<content type="boolean"  />
+		<shortdesc lang="en">Use sudo (without password) when calling 3rd party sotfware.</shortdesc>
+	</parameter>
+	<parameter name="sudo_path" unique="0" required="0">
+		<getopt mixed="--sudo-path=[path]" />
+		<content type="string" default="/usr/bin/sudo"  />
+		<shortdesc lang="en">Path to sudo binary</shortdesc>
+	</parameter>
+</parameters>
+<actions>
+	<action name="on" automatic="0"/>
+	<action name="off" />
+	<action name="reboot" />
+	<action name="status" />
+	<action name="monitor" />
+	<action name="metadata" />
+	<action name="validate-all" />
+</actions>
+</resource-agent>
diff --git a/tests/data/metadata/fence_ifmib.xml b/tests/data/metadata/fence_ifmib.xml
new file mode 100644
index 0000000..a560da8
--- /dev/null
+++ b/tests/data/metadata/fence_ifmib.xml
@@ -0,0 +1,183 @@
+<?xml version="1.0" ?>
+<resource-agent name="fence_ifmib" shortdesc="Fence agent for IF MIB" >
+<longdesc>fence_ifmib is an I/O Fencing agent which can be used with any SNMP IF-MIB capable device. 
+.P
+It was written with managed ethernet switches in mind, in order to fence iSCSI SAN connections. However, there are many devices that support the IF-MIB interface. The agent uses IF-MIB::ifAdminStatus to control the state of an interface.</longdesc>
+<vendor-url>http://www.ietf.org/wg/concluded/ifmib.html</vendor-url>
+<parameters>
+	<parameter name="action" unique="0" required="1">
+		<getopt mixed="-o, --action=[action]" />
+		<content type="string" default="off"  />
+		<shortdesc lang="en">Fencing Action</shortdesc>
+	</parameter>
+	<parameter name="community" unique="0" required="0">
+		<getopt mixed="-c, --community=[community]" />
+		<content type="string"  />
+		<shortdesc lang="en">Set the community string</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="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</shortdesc>
+	</parameter>
+	<parameter name="ipport" unique="0" required="0">
+		<getopt mixed="-u, --ipport=[port]" />
+		<content type="string" default="161"  />
+		<shortdesc lang="en">TCP/UDP port to use for connection with device</shortdesc>
+	</parameter>
+	<parameter name="login" unique="0" required="0">
+		<getopt mixed="-l, --username=[name]" />
+		<content type="string"  />
+		<shortdesc lang="en">Login Name</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="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="port" unique="0" required="1">
+		<getopt mixed="-n, --plug=[id]" />
+		<content type="string"  />
+		<shortdesc lang="en">Physical plug number, name of virtual machine or UUID</shortdesc>
+	</parameter>
+	<parameter name="snmp_auth_prot" unique="0" required="0">
+		<getopt mixed="-b, --snmp-auth-prot=[prot]" />
+		<content type="select"  >
+			<option value="MD5" />
+			<option value="SHA" />
+		</content>
+		<shortdesc lang="en">Set authentication protocol (MD5|SHA)</shortdesc>
+	</parameter>
+	<parameter name="snmp_priv_passwd" unique="0" required="0">
+		<getopt mixed="-P, --snmp-priv-passwd=[pass]" />
+		<content type="string"  />
+		<shortdesc lang="en">Set privacy protocol password</shortdesc>
+	</parameter>
+	<parameter name="snmp_priv_passwd_script" unique="0" required="0">
+		<getopt mixed="-R, --snmp-priv-passwd-script" />
+		<content type="string"  />
+		<shortdesc lang="en">Script to run to retrieve privacy password</shortdesc>
+	</parameter>
+	<parameter name="snmp_priv_prot" unique="0" required="0">
+		<getopt mixed="-B, --snmp-priv-prot=[prot]" />
+		<content type="select"  >
+			<option value="DES" />
+			<option value="AES" />
+		</content>
+		<shortdesc lang="en">Set privacy protocol (DES|AES)</shortdesc>
+	</parameter>
+	<parameter name="snmp_sec_level" unique="0" required="0">
+		<getopt mixed="-E, --snmp-sec-level=[level]" />
+		<content type="select"  >
+			<option value="noAuthNoPriv" />
+			<option value="authNoPriv" />
+			<option value="authPriv" />
+		</content>
+		<shortdesc lang="en">Set security level (noAuthNoPriv|authNoPriv|authPriv)</shortdesc>
+	</parameter>
+	<parameter name="snmp_version" unique="0" required="0">
+		<getopt mixed="-d, --snmp-version=[version]" />
+		<content type="select" default="2c"  >
+			<option value="1" />
+			<option value="2c" />
+			<option value="3" />
+		</content>
+		<shortdesc lang="en">Specifies SNMP version to use (1,2c,3)</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="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="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="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="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>
+	<parameter name="snmpget_path" unique="0" required="0">
+		<getopt mixed="--snmpget-path=[path]" />
+		<content type="string" default="/usr/bin/snmpget"  />
+		<shortdesc lang="en">Path to snmpget binary</shortdesc>
+	</parameter>
+	<parameter name="snmpset_path" unique="0" required="0">
+		<getopt mixed="--snmpset-path=[path]" />
+		<content type="string" default="/usr/bin/snmpset"  />
+		<shortdesc lang="en">Path to snmpset binary</shortdesc>
+	</parameter>
+	<parameter name="snmpwalk_path" unique="0" required="0">
+		<getopt mixed="--snmpwalk-path=[path]" />
+		<content type="string" default="/usr/bin/snmpwalk"  />
+		<shortdesc lang="en">Path to snmpwalk binary</shortdesc>
+	</parameter>
+</parameters>
+<actions>
+	<action name="on" automatic="1"/>
+	<action name="off" />
+	<action name="status" />
+	<action name="list" />
+	<action name="list-status" />
+	<action name="monitor" />
+	<action name="metadata" />
+	<action name="validate-all" />
+</actions>
+</resource-agent>
diff --git a/tests/data/metadata/fence_ilo.xml b/tests/data/metadata/fence_ilo.xml
new file mode 100644
index 0000000..5d183b0
--- /dev/null
+++ b/tests/data/metadata/fence_ilo.xml
@@ -0,0 +1,142 @@
+<?xml version="1.0" ?>
+<resource-agent name="fence_ilo" shortdesc="Fence agent for HP iLO" >
+<symlink name="fence_ilo2" shortdesc="Fence agent for HP iLO2"/>
+<longdesc>fence_ilo is an I/O Fencing agent used for HP servers with the Integrated Light Out (iLO) PCI card.The agent opens an SSL connection to the iLO card. Once the SSL connection is established, the agent is able to communicate with the iLO card through an XML stream.</longdesc>
+<vendor-url>http://www.hp.com</vendor-url>
+<parameters>
+	<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="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="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</shortdesc>
+	</parameter>
+	<parameter name="ipport" unique="0" required="0">
+		<getopt mixed="-u, --ipport=[port]" />
+		<content type="string" default="443"  />
+		<shortdesc lang="en">TCP/UDP port to use for connection with device</shortdesc>
+	</parameter>
+	<parameter name="login" unique="0" required="1">
+		<getopt mixed="-l, --username=[name]" />
+		<content type="string"  />
+		<shortdesc lang="en">Login Name</shortdesc>
+	</parameter>
+	<parameter name="notls" unique="0" required="0">
+		<getopt mixed="-t, --notls" />
+		<content type="boolean"  />
+		<shortdesc lang="en">Disable TLS negotiation, force SSL 3.0</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="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="ribcl" unique="0" required="0">
+		<getopt mixed="-r, --ribcl-version=[version]" />
+		<content type="string"  />
+		<shortdesc lang="en">Force ribcl version to use</shortdesc>
+	</parameter>
+	<parameter name="ssl" unique="0" required="0">
+		<getopt mixed="-z, --ssl" />
+		<content type="boolean" default="1"  />
+		<shortdesc lang="en">SSL connection</shortdesc>
+	</parameter>
+	<parameter name="ssl_insecure" unique="0" required="0">
+		<getopt mixed="--ssl-insecure" />
+		<content type="boolean"  />
+		<shortdesc lang="en">SSL connection without verifying fence device's certificate</shortdesc>
+	</parameter>
+	<parameter name="ssl_secure" unique="0" required="0">
+		<getopt mixed="--ssl-secure" />
+		<content type="boolean"  />
+		<shortdesc lang="en">SSL connection with verifying fence device's certificate</shortdesc>
+	</parameter>
+	<parameter name="tls1.0" unique="0" required="0">
+		<getopt mixed="--tls1.0" />
+		<content type="boolean"  />
+		<shortdesc lang="en">Disable TLS negotiaton, force TLS 1.0</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="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="login_timeout" unique="0" required="0">
+		<getopt mixed="--login-timeout=[seconds]" />
+		<content type="string" default="10"  />
+		<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="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="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="3"  />
+		<shortdesc lang="en">Count of attempts to retry power on</shortdesc>
+	</parameter>
+	<parameter name="gnutlscli_path" unique="0" required="0">
+		<getopt mixed="--gnutlscli-path=[path]" />
+		<content type="string" default="/usr/bin/gnutls-cli"  />
+		<shortdesc lang="en">Path to gnutls-cli binary</shortdesc>
+	</parameter>
+</parameters>
+<actions>
+	<action name="on" automatic="0"/>
+	<action name="off" />
+	<action name="reboot" />
+	<action name="status" />
+	<action name="monitor" />
+	<action name="metadata" />
+	<action name="validate-all" />
+</actions>
+</resource-agent>
diff --git a/tests/data/metadata/fence_ilo2.xml b/tests/data/metadata/fence_ilo2.xml
new file mode 100644
index 0000000..72b1dea
--- /dev/null
+++ b/tests/data/metadata/fence_ilo2.xml
@@ -0,0 +1,142 @@
+<?xml version="1.0" ?>
+<resource-agent name="fence_ilo2" shortdesc="Fence agent for HP iLO" >
+<symlink name="fence_ilo2" shortdesc="Fence agent for HP iLO2"/>
+<longdesc>fence_ilo is an I/O Fencing agent used for HP servers with the Integrated Light Out (iLO) PCI card.The agent opens an SSL connection to the iLO card. Once the SSL connection is established, the agent is able to communicate with the iLO card through an XML stream.</longdesc>
+<vendor-url>http://www.hp.com</vendor-url>
+<parameters>
+	<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="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="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</shortdesc>
+	</parameter>
+	<parameter name="ipport" unique="0" required="0">
+		<getopt mixed="-u, --ipport=[port]" />
+		<content type="string" default="443"  />
+		<shortdesc lang="en">TCP/UDP port to use for connection with device</shortdesc>
+	</parameter>
+	<parameter name="login" unique="0" required="1">
+		<getopt mixed="-l, --username=[name]" />
+		<content type="string"  />
+		<shortdesc lang="en">Login Name</shortdesc>
+	</parameter>
+	<parameter name="notls" unique="0" required="0">
+		<getopt mixed="-t, --notls" />
+		<content type="boolean"  />
+		<shortdesc lang="en">Disable TLS negotiation, force SSL 3.0</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="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="ribcl" unique="0" required="0">
+		<getopt mixed="-r, --ribcl-version=[version]" />
+		<content type="string"  />
+		<shortdesc lang="en">Force ribcl version to use</shortdesc>
+	</parameter>
+	<parameter name="ssl" unique="0" required="0">
+		<getopt mixed="-z, --ssl" />
+		<content type="boolean" default="1"  />
+		<shortdesc lang="en">SSL connection</shortdesc>
+	</parameter>
+	<parameter name="ssl_insecure" unique="0" required="0">
+		<getopt mixed="--ssl-insecure" />
+		<content type="boolean"  />
+		<shortdesc lang="en">SSL connection without verifying fence device's certificate</shortdesc>
+	</parameter>
+	<parameter name="ssl_secure" unique="0" required="0">
+		<getopt mixed="--ssl-secure" />
+		<content type="boolean"  />
+		<shortdesc lang="en">SSL connection with verifying fence device's certificate</shortdesc>
+	</parameter>
+	<parameter name="tls1.0" unique="0" required="0">
+		<getopt mixed="--tls1.0" />
+		<content type="boolean"  />
+		<shortdesc lang="en">Disable TLS negotiaton, force TLS 1.0</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="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="login_timeout" unique="0" required="0">
+		<getopt mixed="--login-timeout=[seconds]" />
+		<content type="string" default="10"  />
+		<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="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="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="3"  />
+		<shortdesc lang="en">Count of attempts to retry power on</shortdesc>
+	</parameter>
+	<parameter name="gnutlscli_path" unique="0" required="0">
+		<getopt mixed="--gnutlscli-path=[path]" />
+		<content type="string" default="/usr/bin/gnutls-cli"  />
+		<shortdesc lang="en">Path to gnutls-cli binary</shortdesc>
+	</parameter>
+</parameters>
+<actions>
+	<action name="on" automatic="0"/>
+	<action name="off" />
+	<action name="reboot" />
+	<action name="status" />
+	<action name="monitor" />
+	<action name="metadata" />
+	<action name="validate-all" />
+</actions>
+</resource-agent>
diff --git a/tests/data/metadata/fence_ilo3.xml b/tests/data/metadata/fence_ilo3.xml
new file mode 100644
index 0000000..6c606ee
--- /dev/null
+++ b/tests/data/metadata/fence_ilo3.xml
@@ -0,0 +1,162 @@
+<?xml version="1.0" ?>
+<resource-agent name="fence_ilo3" shortdesc="Fence agent for IPMI" >
+<symlink name="fence_ilo3" shortdesc="Fence agent for HP iLO3"/>
+<symlink name="fence_ilo4" shortdesc="Fence agent for HP iLO4"/>
+<symlink name="fence_imm" shortdesc="Fence agent for IBM Integrated Management Module"/>
+<symlink name="fence_idrac" shortdesc="Fence agent for Dell iDRAC"/>
+<longdesc>fence_ipmilan is an I/O Fencing agentwhich can be used with machines controlled by IPMI.This agent calls support software ipmitool (http://ipmitool.sf.net/).</longdesc>
+<vendor-url></vendor-url>
+<parameters>
+	<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="auth" unique="0" required="0">
+		<getopt mixed="-A, --auth=[auth]" />
+		<content type="select"  >
+			<option value="md5" />
+			<option value="password" />
+			<option value="none" />
+		</content>
+		<shortdesc lang="en">IPMI Lan Auth type.</shortdesc>
+	</parameter>
+	<parameter name="cipher" unique="0" required="0">
+		<getopt mixed="-C, --cipher=[cipher]" />
+		<content type="string"  />
+		<shortdesc lang="en">Ciphersuite to use (same as ipmitool -C parameter)</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="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</shortdesc>
+	</parameter>
+	<parameter name="ipport" unique="0" required="0">
+		<getopt mixed="-u, --ipport=[port]" />
+		<content type="string" default="623"  />
+		<shortdesc lang="en">TCP/UDP port to use for connection with device</shortdesc>
+	</parameter>
+	<parameter name="lanplus" unique="0" required="0">
+		<getopt mixed="-P, --lanplus" />
+		<content type="boolean" default="1"  />
+		<shortdesc lang="en">Use Lanplus to improve security of connection</shortdesc>
+	</parameter>
+	<parameter name="login" unique="0" required="0">
+		<getopt mixed="-l, --username=[name]" />
+		<content type="string"  />
+		<shortdesc lang="en">Login Name</shortdesc>
+	</parameter>
+	<parameter name="method" unique="0" required="0">
+		<getopt mixed="-m, --method=[method]" />
+		<content type="select" default="cycle"  >
+			<option value="onoff" />
+			<option value="cycle" />
+		</content>
+		<shortdesc lang="en">Method to fence (onoff|cycle)</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="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="privlvl" unique="0" required="0">
+		<getopt mixed="-L, --privlvl=[level]" />
+		<content type="select" default="administrator"  >
+			<option value="callback" />
+			<option value="user" />
+			<option value="operator" />
+			<option value="administrator" />
+		</content>
+		<shortdesc lang="en">Privilege level on IPMI device</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="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="ipmitool_path" unique="0" required="0">
+		<getopt mixed="--ipmitool-path=[path]" />
+		<content type="string" default="/usr/bin/ipmitool"  />
+		<shortdesc lang="en">Path to ipmitool binary</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="power_wait" unique="0" required="0">
+		<getopt mixed="--power-wait=[seconds]" />
+		<content type="string" default="4"  />
+		<shortdesc lang="en">Wait X seconds after issuing ON/OFF</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>
+	<parameter name="sudo" unique="0" required="0">
+		<getopt mixed="--use-sudo" />
+		<content type="boolean"  />
+		<shortdesc lang="en">Use sudo (without password) when calling 3rd party sotfware.</shortdesc>
+	</parameter>
+	<parameter name="sudo_path" unique="0" required="0">
+		<getopt mixed="--sudo-path=[path]" />
+		<content type="string" default="/usr/bin/sudo"  />
+		<shortdesc lang="en">Path to sudo binary</shortdesc>
+	</parameter>
+</parameters>
+<actions>
+	<action name="on" automatic="0"/>
+	<action name="off" />
+	<action name="reboot" />
+	<action name="status" />
+	<action name="monitor" />
+	<action name="metadata" />
+	<action name="validate-all" />
+</actions>
+</resource-agent>
diff --git a/tests/data/metadata/fence_ilo3_ssh.xml b/tests/data/metadata/fence_ilo3_ssh.xml
new file mode 100644
index 0000000..fe5eabf
--- /dev/null
+++ b/tests/data/metadata/fence_ilo3_ssh.xml
@@ -0,0 +1,146 @@
+<?xml version="1.0" ?>
+<resource-agent name="fence_ilo3_ssh" shortdesc="Fence agent for HP iLO over SSH" >
+<symlink name="fence_ilo3_ssh" shortdesc="Fence agent for HP iLO3 over SSH"/>
+<symlink name="fence_ilo4_ssh" shortdesc="Fence agent for HP iLO4 over SSH"/>
+<longdesc>fence_ilo_ssh is a fence agent that connects to iLO device. It logs into device via ssh and reboot a specified outlet. </longdesc>
+<vendor-url>http://www.hp.com</vendor-url>
+<parameters>
+	<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="cmd_prompt" unique="0" required="0">
+		<getopt mixed="-c, --command-prompt=[prompt]" />
+		<content type="string" default="['MP>', 'hpiLO->']"  />
+		<shortdesc lang="en">Force Python regex for command prompt</shortdesc>
+	</parameter>
+	<parameter name="identity_file" unique="0" required="0">
+		<getopt mixed="-k, --identity-file=[filename]" />
+		<content type="string"  />
+		<shortdesc lang="en">Identity file for ssh</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="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</shortdesc>
+	</parameter>
+	<parameter name="ipport" unique="0" required="0">
+		<getopt mixed="-u, --ipport=[port]" />
+		<content type="string" default="23"  />
+		<shortdesc lang="en">TCP/UDP port to use for connection with device</shortdesc>
+	</parameter>
+	<parameter name="login" unique="0" required="1">
+		<getopt mixed="-l, --username=[name]" />
+		<content type="string"  />
+		<shortdesc lang="en">Login Name</shortdesc>
+	</parameter>
+	<parameter name="method" unique="0" required="0">
+		<getopt mixed="-m, --method=[method]" />
+		<content type="select" default="onoff"  >
+			<option value="onoff" />
+			<option value="cycle" />
+		</content>
+		<shortdesc lang="en">Method to fence (onoff|cycle)</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="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="secure" unique="0" required="0">
+		<getopt mixed="-x, --ssh" />
+		<content type="boolean"  />
+		<shortdesc lang="en">SSH connection</shortdesc>
+	</parameter>
+	<parameter name="ssh_options" unique="0" required="0">
+		<getopt mixed="--ssh-options=[options]" />
+		<content type="string"  />
+		<shortdesc lang="en">SSH options to use</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="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="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="power_wait" unique="0" required="0">
+		<getopt mixed="--power-wait=[seconds]" />
+		<content type="string" default="5"  />
+		<shortdesc lang="en">Wait X seconds after issuing ON/OFF</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>
+	<parameter name="ssh_path" unique="0" required="0">
+		<getopt mixed="--ssh-path=[path]" />
+		<content type="string" default="/usr/bin/ssh"  />
+		<shortdesc lang="en">Path to ssh binary</shortdesc>
+	</parameter>
+	<parameter name="telnet_path" unique="0" required="0">
+		<getopt mixed="--telnet-path=[path]" />
+		<content type="string" default="/usr/bin/telnet"  />
+		<shortdesc lang="en">Path to telnet binary</shortdesc>
+	</parameter>
+</parameters>
+<actions>
+	<action name="on" automatic="0"/>
+	<action name="off" />
+	<action name="reboot" />
+	<action name="status" />
+	<action name="monitor" />
+	<action name="metadata" />
+	<action name="validate-all" />
+</actions>
+</resource-agent>
diff --git a/tests/data/metadata/fence_ilo4.xml b/tests/data/metadata/fence_ilo4.xml
new file mode 100644
index 0000000..53bb578
--- /dev/null
+++ b/tests/data/metadata/fence_ilo4.xml
@@ -0,0 +1,162 @@
+<?xml version="1.0" ?>
+<resource-agent name="fence_ilo4" shortdesc="Fence agent for IPMI" >
+<symlink name="fence_ilo3" shortdesc="Fence agent for HP iLO3"/>
+<symlink name="fence_ilo4" shortdesc="Fence agent for HP iLO4"/>
+<symlink name="fence_imm" shortdesc="Fence agent for IBM Integrated Management Module"/>
+<symlink name="fence_idrac" shortdesc="Fence agent for Dell iDRAC"/>
+<longdesc>fence_ipmilan is an I/O Fencing agentwhich can be used with machines controlled by IPMI.This agent calls support software ipmitool (http://ipmitool.sf.net/).</longdesc>
+<vendor-url></vendor-url>
+<parameters>
+	<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="auth" unique="0" required="0">
+		<getopt mixed="-A, --auth=[auth]" />
+		<content type="select"  >
+			<option value="md5" />
+			<option value="password" />
+			<option value="none" />
+		</content>
+		<shortdesc lang="en">IPMI Lan Auth type.</shortdesc>
+	</parameter>
+	<parameter name="cipher" unique="0" required="0">
+		<getopt mixed="-C, --cipher=[cipher]" />
+		<content type="string"  />
+		<shortdesc lang="en">Ciphersuite to use (same as ipmitool -C parameter)</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="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</shortdesc>
+	</parameter>
+	<parameter name="ipport" unique="0" required="0">
+		<getopt mixed="-u, --ipport=[port]" />
+		<content type="string" default="623"  />
+		<shortdesc lang="en">TCP/UDP port to use for connection with device</shortdesc>
+	</parameter>
+	<parameter name="lanplus" unique="0" required="0">
+		<getopt mixed="-P, --lanplus" />
+		<content type="boolean" default="1"  />
+		<shortdesc lang="en">Use Lanplus to improve security of connection</shortdesc>
+	</parameter>
+	<parameter name="login" unique="0" required="0">
+		<getopt mixed="-l, --username=[name]" />
+		<content type="string"  />
+		<shortdesc lang="en">Login Name</shortdesc>
+	</parameter>
+	<parameter name="method" unique="0" required="0">
+		<getopt mixed="-m, --method=[method]" />
+		<content type="select" default="onoff"  >
+			<option value="onoff" />
+			<option value="cycle" />
+		</content>
+		<shortdesc lang="en">Method to fence (onoff|cycle)</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="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="privlvl" unique="0" required="0">
+		<getopt mixed="-L, --privlvl=[level]" />
+		<content type="select" default="administrator"  >
+			<option value="callback" />
+			<option value="user" />
+			<option value="operator" />
+			<option value="administrator" />
+		</content>
+		<shortdesc lang="en">Privilege level on IPMI device</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="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="ipmitool_path" unique="0" required="0">
+		<getopt mixed="--ipmitool-path=[path]" />
+		<content type="string" default="/usr/bin/ipmitool"  />
+		<shortdesc lang="en">Path to ipmitool binary</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="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="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>
+	<parameter name="sudo" unique="0" required="0">
+		<getopt mixed="--use-sudo" />
+		<content type="boolean"  />
+		<shortdesc lang="en">Use sudo (without password) when calling 3rd party sotfware.</shortdesc>
+	</parameter>
+	<parameter name="sudo_path" unique="0" required="0">
+		<getopt mixed="--sudo-path=[path]" />
+		<content type="string" default="/usr/bin/sudo"  />
+		<shortdesc lang="en">Path to sudo binary</shortdesc>
+	</parameter>
+</parameters>
+<actions>
+	<action name="on" automatic="0"/>
+	<action name="off" />
+	<action name="reboot" />
+	<action name="status" />
+	<action name="monitor" />
+	<action name="metadata" />
+	<action name="validate-all" />
+</actions>
+</resource-agent>
diff --git a/tests/data/metadata/fence_ilo4_ssh.xml b/tests/data/metadata/fence_ilo4_ssh.xml
new file mode 100644
index 0000000..de64cf1
--- /dev/null
+++ b/tests/data/metadata/fence_ilo4_ssh.xml
@@ -0,0 +1,146 @@
+<?xml version="1.0" ?>
+<resource-agent name="fence_ilo4_ssh" shortdesc="Fence agent for HP iLO over SSH" >
+<symlink name="fence_ilo3_ssh" shortdesc="Fence agent for HP iLO3 over SSH"/>
+<symlink name="fence_ilo4_ssh" shortdesc="Fence agent for HP iLO4 over SSH"/>
+<longdesc>fence_ilo_ssh is a fence agent that connects to iLO device. It logs into device via ssh and reboot a specified outlet. </longdesc>
+<vendor-url>http://www.hp.com</vendor-url>
+<parameters>
+	<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="cmd_prompt" unique="0" required="0">
+		<getopt mixed="-c, --command-prompt=[prompt]" />
+		<content type="string" default="['MP>', 'hpiLO->']"  />
+		<shortdesc lang="en">Force Python regex for command prompt</shortdesc>
+	</parameter>
+	<parameter name="identity_file" unique="0" required="0">
+		<getopt mixed="-k, --identity-file=[filename]" />
+		<content type="string"  />
+		<shortdesc lang="en">Identity file for ssh</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="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</shortdesc>
+	</parameter>
+	<parameter name="ipport" unique="0" required="0">
+		<getopt mixed="-u, --ipport=[port]" />
+		<content type="string" default="23"  />
+		<shortdesc lang="en">TCP/UDP port to use for connection with device</shortdesc>
+	</parameter>
+	<parameter name="login" unique="0" required="1">
+		<getopt mixed="-l, --username=[name]" />
+		<content type="string"  />
+		<shortdesc lang="en">Login Name</shortdesc>
+	</parameter>
+	<parameter name="method" unique="0" required="0">
+		<getopt mixed="-m, --method=[method]" />
+		<content type="select" default="onoff"  >
+			<option value="onoff" />
+			<option value="cycle" />
+		</content>
+		<shortdesc lang="en">Method to fence (onoff|cycle)</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="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="secure" unique="0" required="0">
+		<getopt mixed="-x, --ssh" />
+		<content type="boolean"  />
+		<shortdesc lang="en">SSH connection</shortdesc>
+	</parameter>
+	<parameter name="ssh_options" unique="0" required="0">
+		<getopt mixed="--ssh-options=[options]" />
+		<content type="string"  />
+		<shortdesc lang="en">SSH options to use</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="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="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="power_wait" unique="0" required="0">
+		<getopt mixed="--power-wait=[seconds]" />
+		<content type="string" default="5"  />
+		<shortdesc lang="en">Wait X seconds after issuing ON/OFF</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>
+	<parameter name="ssh_path" unique="0" required="0">
+		<getopt mixed="--ssh-path=[path]" />
+		<content type="string" default="/usr/bin/ssh"  />
+		<shortdesc lang="en">Path to ssh binary</shortdesc>
+	</parameter>
+	<parameter name="telnet_path" unique="0" required="0">
+		<getopt mixed="--telnet-path=[path]" />
+		<content type="string" default="/usr/bin/telnet"  />
+		<shortdesc lang="en">Path to telnet binary</shortdesc>
+	</parameter>
+</parameters>
+<actions>
+	<action name="on" automatic="0"/>
+	<action name="off" />
+	<action name="reboot" />
+	<action name="status" />
+	<action name="monitor" />
+	<action name="metadata" />
+	<action name="validate-all" />
+</actions>
+</resource-agent>
diff --git a/tests/data/metadata/fence_ilo_moonshot.xml b/tests/data/metadata/fence_ilo_moonshot.xml
new file mode 100644
index 0000000..39b745d
--- /dev/null
+++ b/tests/data/metadata/fence_ilo_moonshot.xml
@@ -0,0 +1,143 @@
+<?xml version="1.0" ?>
+<resource-agent name="fence_ilo_moonshot" shortdesc="Fence agent for HP Moonshot iLO" >
+<longdesc></longdesc>
+<vendor-url>http://www.hp.com</vendor-url>
+<parameters>
+	<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="cmd_prompt" unique="0" required="0">
+		<getopt mixed="-c, --command-prompt=[prompt]" />
+		<content type="string" default="['MP>', 'hpiLO->']"  />
+		<shortdesc lang="en">Force Python regex for command prompt</shortdesc>
+	</parameter>
+	<parameter name="identity_file" unique="0" required="0">
+		<getopt mixed="-k, --identity-file=[filename]" />
+		<content type="string"  />
+		<shortdesc lang="en">Identity file for ssh</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="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</shortdesc>
+	</parameter>
+	<parameter name="ipport" unique="0" required="0">
+		<getopt mixed="-u, --ipport=[port]" />
+		<content type="string" default="22"  />
+		<shortdesc lang="en">TCP/UDP port to use for connection with device</shortdesc>
+	</parameter>
+	<parameter name="login" unique="0" required="1">
+		<getopt mixed="-l, --username=[name]" />
+		<content type="string"  />
+		<shortdesc lang="en">Login Name</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="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="port" unique="0" required="1">
+		<getopt mixed="-n, --plug=[id]" />
+		<content type="string"  />
+		<shortdesc lang="en">Physical plug number, name of virtual machine or UUID</shortdesc>
+	</parameter>
+	<parameter name="secure" unique="0" required="0">
+		<getopt mixed="-x, --ssh" />
+		<content type="boolean" default="1"  />
+		<shortdesc lang="en">SSH connection</shortdesc>
+	</parameter>
+	<parameter name="ssh_options" unique="0" required="0">
+		<getopt mixed="--ssh-options=[options]" />
+		<content type="string"  />
+		<shortdesc lang="en">SSH options to use</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="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="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="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="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>
+	<parameter name="ssh_path" unique="0" required="0">
+		<getopt mixed="--ssh-path=[path]" />
+		<content type="string" default="/usr/bin/ssh"  />
+		<shortdesc lang="en">Path to ssh binary</shortdesc>
+	</parameter>
+</parameters>
+<actions>
+	<action name="on" automatic="0"/>
+	<action name="off" />
+	<action name="reboot" />
+	<action name="status" />
+	<action name="list" />
+	<action name="list-status" />
+	<action name="monitor" />
+	<action name="metadata" />
+	<action name="validate-all" />
+</actions>
+</resource-agent>
diff --git a/tests/data/metadata/fence_ilo_mp.xml b/tests/data/metadata/fence_ilo_mp.xml
new file mode 100644
index 0000000..093d848
--- /dev/null
+++ b/tests/data/metadata/fence_ilo_mp.xml
@@ -0,0 +1,136 @@
+<?xml version="1.0" ?>
+<resource-agent name="fence_ilo_mp" shortdesc="Fence agent for HP iLO MP" >
+<longdesc></longdesc>
+<vendor-url>http://www.hp.com</vendor-url>
+<parameters>
+	<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="cmd_prompt" unique="0" required="0">
+		<getopt mixed="-c, --command-prompt=[prompt]" />
+		<content type="string" default="['MP>', 'hpiLO->']"  />
+		<shortdesc lang="en">Force Python regex for command prompt</shortdesc>
+	</parameter>
+	<parameter name="identity_file" unique="0" required="0">
+		<getopt mixed="-k, --identity-file=[filename]" />
+		<content type="string"  />
+		<shortdesc lang="en">Identity file for ssh</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="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</shortdesc>
+	</parameter>
+	<parameter name="ipport" unique="0" required="0">
+		<getopt mixed="-u, --ipport=[port]" />
+		<content type="string" default="23"  />
+		<shortdesc lang="en">TCP/UDP port to use for connection with device</shortdesc>
+	</parameter>
+	<parameter name="login" unique="0" required="1">
+		<getopt mixed="-l, --username=[name]" />
+		<content type="string"  />
+		<shortdesc lang="en">Login Name</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="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="secure" unique="0" required="0">
+		<getopt mixed="-x, --ssh" />
+		<content type="boolean"  />
+		<shortdesc lang="en">SSH connection</shortdesc>
+	</parameter>
+	<parameter name="ssh_options" unique="0" required="0">
+		<getopt mixed="--ssh-options=[options]" />
+		<content type="string"  />
+		<shortdesc lang="en">SSH options to use</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="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="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="power_wait" unique="0" required="0">
+		<getopt mixed="--power-wait=[seconds]" />
+		<content type="string" default="5"  />
+		<shortdesc lang="en">Wait X seconds after issuing ON/OFF</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>
+	<parameter name="ssh_path" unique="0" required="0">
+		<getopt mixed="--ssh-path=[path]" />
+		<content type="string" default="/usr/bin/ssh"  />
+		<shortdesc lang="en">Path to ssh binary</shortdesc>
+	</parameter>
+	<parameter name="telnet_path" unique="0" required="0">
+		<getopt mixed="--telnet-path=[path]" />
+		<content type="string" default="/usr/bin/telnet"  />
+		<shortdesc lang="en">Path to telnet binary</shortdesc>
+	</parameter>
+</parameters>
+<actions>
+	<action name="on" automatic="0"/>
+	<action name="off" />
+	<action name="reboot" />
+	<action name="status" />
+	<action name="monitor" />
+	<action name="metadata" />
+	<action name="validate-all" />
+</actions>
+</resource-agent>
diff --git a/tests/data/metadata/fence_ilo_ssh.xml b/tests/data/metadata/fence_ilo_ssh.xml
new file mode 100644
index 0000000..338dc56
--- /dev/null
+++ b/tests/data/metadata/fence_ilo_ssh.xml
@@ -0,0 +1,146 @@
+<?xml version="1.0" ?>
+<resource-agent name="fence_ilo_ssh" shortdesc="Fence agent for HP iLO over SSH" >
+<symlink name="fence_ilo3_ssh" shortdesc="Fence agent for HP iLO3 over SSH"/>
+<symlink name="fence_ilo4_ssh" shortdesc="Fence agent for HP iLO4 over SSH"/>
+<longdesc>fence_ilo_ssh is a fence agent that connects to iLO device. It logs into device via ssh and reboot a specified outlet. </longdesc>
+<vendor-url>http://www.hp.com</vendor-url>
+<parameters>
+	<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="cmd_prompt" unique="0" required="0">
+		<getopt mixed="-c, --command-prompt=[prompt]" />
+		<content type="string" default="['MP>', 'hpiLO->']"  />
+		<shortdesc lang="en">Force Python regex for command prompt</shortdesc>
+	</parameter>
+	<parameter name="identity_file" unique="0" required="0">
+		<getopt mixed="-k, --identity-file=[filename]" />
+		<content type="string"  />
+		<shortdesc lang="en">Identity file for ssh</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="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</shortdesc>
+	</parameter>
+	<parameter name="ipport" unique="0" required="0">
+		<getopt mixed="-u, --ipport=[port]" />
+		<content type="string" default="23"  />
+		<shortdesc lang="en">TCP/UDP port to use for connection with device</shortdesc>
+	</parameter>
+	<parameter name="login" unique="0" required="1">
+		<getopt mixed="-l, --username=[name]" />
+		<content type="string"  />
+		<shortdesc lang="en">Login Name</shortdesc>
+	</parameter>
+	<parameter name="method" unique="0" required="0">
+		<getopt mixed="-m, --method=[method]" />
+		<content type="select" default="onoff"  >
+			<option value="onoff" />
+			<option value="cycle" />
+		</content>
+		<shortdesc lang="en">Method to fence (onoff|cycle)</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="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="secure" unique="0" required="0">
+		<getopt mixed="-x, --ssh" />
+		<content type="boolean"  />
+		<shortdesc lang="en">SSH connection</shortdesc>
+	</parameter>
+	<parameter name="ssh_options" unique="0" required="0">
+		<getopt mixed="--ssh-options=[options]" />
+		<content type="string"  />
+		<shortdesc lang="en">SSH options to use</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="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="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="power_wait" unique="0" required="0">
+		<getopt mixed="--power-wait=[seconds]" />
+		<content type="string" default="5"  />
+		<shortdesc lang="en">Wait X seconds after issuing ON/OFF</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>
+	<parameter name="ssh_path" unique="0" required="0">
+		<getopt mixed="--ssh-path=[path]" />
+		<content type="string" default="/usr/bin/ssh"  />
+		<shortdesc lang="en">Path to ssh binary</shortdesc>
+	</parameter>
+	<parameter name="telnet_path" unique="0" required="0">
+		<getopt mixed="--telnet-path=[path]" />
+		<content type="string" default="/usr/bin/telnet"  />
+		<shortdesc lang="en">Path to telnet binary</shortdesc>
+	</parameter>
+</parameters>
+<actions>
+	<action name="on" automatic="0"/>
+	<action name="off" />
+	<action name="reboot" />
+	<action name="status" />
+	<action name="monitor" />
+	<action name="metadata" />
+	<action name="validate-all" />
+</actions>
+</resource-agent>
diff --git a/tests/data/metadata/fence_imm.xml b/tests/data/metadata/fence_imm.xml
new file mode 100644
index 0000000..eae6ab4
--- /dev/null
+++ b/tests/data/metadata/fence_imm.xml
@@ -0,0 +1,162 @@
+<?xml version="1.0" ?>
+<resource-agent name="fence_imm" shortdesc="Fence agent for IPMI" >
+<symlink name="fence_ilo3" shortdesc="Fence agent for HP iLO3"/>
+<symlink name="fence_ilo4" shortdesc="Fence agent for HP iLO4"/>
+<symlink name="fence_imm" shortdesc="Fence agent for IBM Integrated Management Module"/>
+<symlink name="fence_idrac" shortdesc="Fence agent for Dell iDRAC"/>
+<longdesc>fence_ipmilan is an I/O Fencing agentwhich can be used with machines controlled by IPMI.This agent calls support software ipmitool (http://ipmitool.sf.net/).</longdesc>
+<vendor-url></vendor-url>
+<parameters>
+	<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="auth" unique="0" required="0">
+		<getopt mixed="-A, --auth=[auth]" />
+		<content type="select"  >
+			<option value="md5" />
+			<option value="password" />
+			<option value="none" />
+		</content>
+		<shortdesc lang="en">IPMI Lan Auth type.</shortdesc>
+	</parameter>
+	<parameter name="cipher" unique="0" required="0">
+		<getopt mixed="-C, --cipher=[cipher]" />
+		<content type="string"  />
+		<shortdesc lang="en">Ciphersuite to use (same as ipmitool -C parameter)</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="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</shortdesc>
+	</parameter>
+	<parameter name="ipport" unique="0" required="0">
+		<getopt mixed="-u, --ipport=[port]" />
+		<content type="string" default="623"  />
+		<shortdesc lang="en">TCP/UDP port to use for connection with device</shortdesc>
+	</parameter>
+	<parameter name="lanplus" unique="0" required="0">
+		<getopt mixed="-P, --lanplus" />
+		<content type="boolean" default="0"  />
+		<shortdesc lang="en">Use Lanplus to improve security of connection</shortdesc>
+	</parameter>
+	<parameter name="login" unique="0" required="0">
+		<getopt mixed="-l, --username=[name]" />
+		<content type="string"  />
+		<shortdesc lang="en">Login Name</shortdesc>
+	</parameter>
+	<parameter name="method" unique="0" required="0">
+		<getopt mixed="-m, --method=[method]" />
+		<content type="select" default="onoff"  >
+			<option value="onoff" />
+			<option value="cycle" />
+		</content>
+		<shortdesc lang="en">Method to fence (onoff|cycle)</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="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="privlvl" unique="0" required="0">
+		<getopt mixed="-L, --privlvl=[level]" />
+		<content type="select" default="administrator"  >
+			<option value="callback" />
+			<option value="user" />
+			<option value="operator" />
+			<option value="administrator" />
+		</content>
+		<shortdesc lang="en">Privilege level on IPMI device</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="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="ipmitool_path" unique="0" required="0">
+		<getopt mixed="--ipmitool-path=[path]" />
+		<content type="string" default="/usr/bin/ipmitool"  />
+		<shortdesc lang="en">Path to ipmitool binary</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="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="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>
+	<parameter name="sudo" unique="0" required="0">
+		<getopt mixed="--use-sudo" />
+		<content type="boolean"  />
+		<shortdesc lang="en">Use sudo (without password) when calling 3rd party sotfware.</shortdesc>
+	</parameter>
+	<parameter name="sudo_path" unique="0" required="0">
+		<getopt mixed="--sudo-path=[path]" />
+		<content type="string" default="/usr/bin/sudo"  />
+		<shortdesc lang="en">Path to sudo binary</shortdesc>
+	</parameter>
+</parameters>
+<actions>
+	<action name="on" automatic="0"/>
+	<action name="off" />
+	<action name="reboot" />
+	<action name="status" />
+	<action name="monitor" />
+	<action name="metadata" />
+	<action name="validate-all" />
+</actions>
+</resource-agent>
diff --git a/tests/data/metadata/fence_intelmodular.xml b/tests/data/metadata/fence_intelmodular.xml
new file mode 100644
index 0000000..8224858
--- /dev/null
+++ b/tests/data/metadata/fence_intelmodular.xml
@@ -0,0 +1,184 @@
+<?xml version="1.0" ?>
+<resource-agent name="fence_intelmodular" shortdesc="Fence agent for Intel Modular" >
+<longdesc>fence_intelmodular is an I/O Fencing agent which can be used with Intel Modular device (tested on Intel MFSYS25, should work with MFSYS35 as well). 
+.P
+Note: Since firmware update version 2.7, SNMP v2 write support is removed, and replaced by SNMP v3 support. So agent now has default SNMP version 3. If you are using older firmware, please supply -d for command line and snmp_version option for your cluster.conf.</longdesc>
+<vendor-url>http://www.intel.com</vendor-url>
+<parameters>
+	<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="community" unique="0" required="0">
+		<getopt mixed="-c, --community=[community]" />
+		<content type="string"  />
+		<shortdesc lang="en">Set the community string</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="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</shortdesc>
+	</parameter>
+	<parameter name="ipport" unique="0" required="0">
+		<getopt mixed="-u, --ipport=[port]" />
+		<content type="string" default="161"  />
+		<shortdesc lang="en">TCP/UDP port to use for connection with device</shortdesc>
+	</parameter>
+	<parameter name="login" unique="0" required="0">
+		<getopt mixed="-l, --username=[name]" />
+		<content type="string"  />
+		<shortdesc lang="en">Login Name</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="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="port" unique="0" required="1">
+		<getopt mixed="-n, --plug=[id]" />
+		<content type="string"  />
+		<shortdesc lang="en">Physical plug number, name of virtual machine or UUID</shortdesc>
+	</parameter>
+	<parameter name="snmp_auth_prot" unique="0" required="0">
+		<getopt mixed="-b, --snmp-auth-prot=[prot]" />
+		<content type="select"  >
+			<option value="MD5" />
+			<option value="SHA" />
+		</content>
+		<shortdesc lang="en">Set authentication protocol (MD5|SHA)</shortdesc>
+	</parameter>
+	<parameter name="snmp_priv_passwd" unique="0" required="0">
+		<getopt mixed="-P, --snmp-priv-passwd=[pass]" />
+		<content type="string"  />
+		<shortdesc lang="en">Set privacy protocol password</shortdesc>
+	</parameter>
+	<parameter name="snmp_priv_passwd_script" unique="0" required="0">
+		<getopt mixed="-R, --snmp-priv-passwd-script" />
+		<content type="string"  />
+		<shortdesc lang="en">Script to run to retrieve privacy password</shortdesc>
+	</parameter>
+	<parameter name="snmp_priv_prot" unique="0" required="0">
+		<getopt mixed="-B, --snmp-priv-prot=[prot]" />
+		<content type="select"  >
+			<option value="DES" />
+			<option value="AES" />
+		</content>
+		<shortdesc lang="en">Set privacy protocol (DES|AES)</shortdesc>
+	</parameter>
+	<parameter name="snmp_sec_level" unique="0" required="0">
+		<getopt mixed="-E, --snmp-sec-level=[level]" />
+		<content type="select"  >
+			<option value="noAuthNoPriv" />
+			<option value="authNoPriv" />
+			<option value="authPriv" />
+		</content>
+		<shortdesc lang="en">Set security level (noAuthNoPriv|authNoPriv|authPriv)</shortdesc>
+	</parameter>
+	<parameter name="snmp_version" unique="0" required="0">
+		<getopt mixed="-d, --snmp-version=[version]" />
+		<content type="select"  >
+			<option value="1" />
+			<option value="2c" />
+			<option value="3" />
+		</content>
+		<shortdesc lang="en">Specifies SNMP version to use (1,2c,3)</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="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="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="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="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>
+	<parameter name="snmpget_path" unique="0" required="0">
+		<getopt mixed="--snmpget-path=[path]" />
+		<content type="string" default="/usr/bin/snmpget"  />
+		<shortdesc lang="en">Path to snmpget binary</shortdesc>
+	</parameter>
+	<parameter name="snmpset_path" unique="0" required="0">
+		<getopt mixed="--snmpset-path=[path]" />
+		<content type="string" default="/usr/bin/snmpset"  />
+		<shortdesc lang="en">Path to snmpset binary</shortdesc>
+	</parameter>
+	<parameter name="snmpwalk_path" unique="0" required="0">
+		<getopt mixed="--snmpwalk-path=[path]" />
+		<content type="string" default="/usr/bin/snmpwalk"  />
+		<shortdesc lang="en">Path to snmpwalk binary</shortdesc>
+	</parameter>
+</parameters>
+<actions>
+	<action name="on" automatic="0"/>
+	<action name="off" />
+	<action name="reboot" />
+	<action name="status" />
+	<action name="list" />
+	<action name="list-status" />
+	<action name="monitor" />
+	<action name="metadata" />
+	<action name="validate-all" />
+</actions>
+</resource-agent>
diff --git a/tests/data/metadata/fence_ipdu.xml b/tests/data/metadata/fence_ipdu.xml
new file mode 100644
index 0000000..22756e9
--- /dev/null
+++ b/tests/data/metadata/fence_ipdu.xml
@@ -0,0 +1,182 @@
+<?xml version="1.0" ?>
+<resource-agent name="fence_ipdu" shortdesc="Fence agent for iPDU over SNMP" >
+<longdesc>fence_ipdu is an I/O Fencing agent which can be used with the IBM iPDU network power switch. It logs into a device via SNMP and reboots a specified outlet. It supports SNMP v3 with all combinations of authenticity/privacy settings.</longdesc>
+<vendor-url>http://www.ibm.com</vendor-url>
+<parameters>
+	<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="community" unique="0" required="0">
+		<getopt mixed="-c, --community=[community]" />
+		<content type="string" default="private"  />
+		<shortdesc lang="en">Set the community string</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="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</shortdesc>
+	</parameter>
+	<parameter name="ipport" unique="0" required="0">
+		<getopt mixed="-u, --ipport=[port]" />
+		<content type="string" default="161"  />
+		<shortdesc lang="en">TCP/UDP port to use for connection with device</shortdesc>
+	</parameter>
+	<parameter name="login" unique="0" required="0">
+		<getopt mixed="-l, --username=[name]" />
+		<content type="string"  />
+		<shortdesc lang="en">Login Name</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="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="port" unique="0" required="1">
+		<getopt mixed="-n, --plug=[id]" />
+		<content type="string"  />
+		<shortdesc lang="en">Physical plug number, name of virtual machine or UUID</shortdesc>
+	</parameter>
+	<parameter name="snmp_auth_prot" unique="0" required="0">
+		<getopt mixed="-b, --snmp-auth-prot=[prot]" />
+		<content type="select"  >
+			<option value="MD5" />
+			<option value="SHA" />
+		</content>
+		<shortdesc lang="en">Set authentication protocol (MD5|SHA)</shortdesc>
+	</parameter>
+	<parameter name="snmp_priv_passwd" unique="0" required="0">
+		<getopt mixed="-P, --snmp-priv-passwd=[pass]" />
+		<content type="string"  />
+		<shortdesc lang="en">Set privacy protocol password</shortdesc>
+	</parameter>
+	<parameter name="snmp_priv_passwd_script" unique="0" required="0">
+		<getopt mixed="-R, --snmp-priv-passwd-script" />
+		<content type="string"  />
+		<shortdesc lang="en">Script to run to retrieve privacy password</shortdesc>
+	</parameter>
+	<parameter name="snmp_priv_prot" unique="0" required="0">
+		<getopt mixed="-B, --snmp-priv-prot=[prot]" />
+		<content type="select"  >
+			<option value="DES" />
+			<option value="AES" />
+		</content>
+		<shortdesc lang="en">Set privacy protocol (DES|AES)</shortdesc>
+	</parameter>
+	<parameter name="snmp_sec_level" unique="0" required="0">
+		<getopt mixed="-E, --snmp-sec-level=[level]" />
+		<content type="select"  >
+			<option value="noAuthNoPriv" />
+			<option value="authNoPriv" />
+			<option value="authPriv" />
+		</content>
+		<shortdesc lang="en">Set security level (noAuthNoPriv|authNoPriv|authPriv)</shortdesc>
+	</parameter>
+	<parameter name="snmp_version" unique="0" required="0">
+		<getopt mixed="-d, --snmp-version=[version]" />
+		<content type="select" default="3"  >
+			<option value="1" />
+			<option value="2c" />
+			<option value="3" />
+		</content>
+		<shortdesc lang="en">Specifies SNMP version to use (1,2c,3)</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="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="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="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="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>
+	<parameter name="snmpget_path" unique="0" required="0">
+		<getopt mixed="--snmpget-path=[path]" />
+		<content type="string" default="/usr/bin/snmpget"  />
+		<shortdesc lang="en">Path to snmpget binary</shortdesc>
+	</parameter>
+	<parameter name="snmpset_path" unique="0" required="0">
+		<getopt mixed="--snmpset-path=[path]" />
+		<content type="string" default="/usr/bin/snmpset"  />
+		<shortdesc lang="en">Path to snmpset binary</shortdesc>
+	</parameter>
+	<parameter name="snmpwalk_path" unique="0" required="0">
+		<getopt mixed="--snmpwalk-path=[path]" />
+		<content type="string" default="/usr/bin/snmpwalk"  />
+		<shortdesc lang="en">Path to snmpwalk binary</shortdesc>
+	</parameter>
+</parameters>
+<actions>
+	<action name="on" automatic="0"/>
+	<action name="off" />
+	<action name="reboot" />
+	<action name="status" />
+	<action name="list" />
+	<action name="list-status" />
+	<action name="monitor" />
+	<action name="metadata" />
+	<action name="validate-all" />
+</actions>
+</resource-agent>
diff --git a/tests/data/metadata/fence_ipmilan.xml b/tests/data/metadata/fence_ipmilan.xml
new file mode 100644
index 0000000..3f8b96a
--- /dev/null
+++ b/tests/data/metadata/fence_ipmilan.xml
@@ -0,0 +1,162 @@
+<?xml version="1.0" ?>
+<resource-agent name="fence_ipmilan" shortdesc="Fence agent for IPMI" >
+<symlink name="fence_ilo3" shortdesc="Fence agent for HP iLO3"/>
+<symlink name="fence_ilo4" shortdesc="Fence agent for HP iLO4"/>
+<symlink name="fence_imm" shortdesc="Fence agent for IBM Integrated Management Module"/>
+<symlink name="fence_idrac" shortdesc="Fence agent for Dell iDRAC"/>
+<longdesc>fence_ipmilan is an I/O Fencing agentwhich can be used with machines controlled by IPMI.This agent calls support software ipmitool (http://ipmitool.sf.net/).</longdesc>
+<vendor-url></vendor-url>
+<parameters>
+	<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="auth" unique="0" required="0">
+		<getopt mixed="-A, --auth=[auth]" />
+		<content type="select"  >
+			<option value="md5" />
+			<option value="password" />
+			<option value="none" />
+		</content>
+		<shortdesc lang="en">IPMI Lan Auth type.</shortdesc>
+	</parameter>
+	<parameter name="cipher" unique="0" required="0">
+		<getopt mixed="-C, --cipher=[cipher]" />
+		<content type="string"  />
+		<shortdesc lang="en">Ciphersuite to use (same as ipmitool -C parameter)</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="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</shortdesc>
+	</parameter>
+	<parameter name="ipport" unique="0" required="0">
+		<getopt mixed="-u, --ipport=[port]" />
+		<content type="string" default="623"  />
+		<shortdesc lang="en">TCP/UDP port to use for connection with device</shortdesc>
+	</parameter>
+	<parameter name="lanplus" unique="0" required="0">
+		<getopt mixed="-P, --lanplus" />
+		<content type="boolean" default="0"  />
+		<shortdesc lang="en">Use Lanplus to improve security of connection</shortdesc>
+	</parameter>
+	<parameter name="login" unique="0" required="0">
+		<getopt mixed="-l, --username=[name]" />
+		<content type="string"  />
+		<shortdesc lang="en">Login Name</shortdesc>
+	</parameter>
+	<parameter name="method" unique="0" required="0">
+		<getopt mixed="-m, --method=[method]" />
+		<content type="select" default="onoff"  >
+			<option value="onoff" />
+			<option value="cycle" />
+		</content>
+		<shortdesc lang="en">Method to fence (onoff|cycle)</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="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="privlvl" unique="0" required="0">
+		<getopt mixed="-L, --privlvl=[level]" />
+		<content type="select" default="administrator"  >
+			<option value="callback" />
+			<option value="user" />
+			<option value="operator" />
+			<option value="administrator" />
+		</content>
+		<shortdesc lang="en">Privilege level on IPMI device</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="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="ipmitool_path" unique="0" required="0">
+		<getopt mixed="--ipmitool-path=[path]" />
+		<content type="string" default="/usr/bin/ipmitool"  />
+		<shortdesc lang="en">Path to ipmitool binary</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="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="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>
+	<parameter name="sudo" unique="0" required="0">
+		<getopt mixed="--use-sudo" />
+		<content type="boolean"  />
+		<shortdesc lang="en">Use sudo (without password) when calling 3rd party sotfware.</shortdesc>
+	</parameter>
+	<parameter name="sudo_path" unique="0" required="0">
+		<getopt mixed="--sudo-path=[path]" />
+		<content type="string" default="/usr/bin/sudo"  />
+		<shortdesc lang="en">Path to sudo binary</shortdesc>
+	</parameter>
+</parameters>
+<actions>
+	<action name="on" automatic="0"/>
+	<action name="off" />
+	<action name="reboot" />
+	<action name="status" />
+	<action name="monitor" />
+	<action name="metadata" />
+	<action name="validate-all" />
+</actions>
+</resource-agent>
diff --git a/tests/data/metadata/fence_kdump.xml b/tests/data/metadata/fence_kdump.xml
new file mode 100644
index 0000000..08967fd
--- /dev/null
+++ b/tests/data/metadata/fence_kdump.xml
@@ -0,0 +1,52 @@
+<?xml version="1.0" ?>
+<resource-agent name="fence_kdump" shortdesc="Fence agent for use with kdump">
+<longdesc>The fence_kdump agent is intended to be used with with kdump service.</longdesc>
+<vendor-url>http://www.kernel.org/pub/linux/utils/kernel/kexec/</vendor-url>
+<parameters>
+	<parameter name="nodename" unique="0" required="0">
+		<getopt mixed="-n, --nodename" />
+		<content type="string" />
+		<shortdesc lang="en">Name or IP address of node to be fenced</shortdesc>
+	</parameter>
+	<parameter name="ipport" unique="0" required="0">
+		<getopt mixed="-p, --ipport" />
+		<content type="string" default="7410" />
+		<shortdesc lang="en">Port number</shortdesc>
+	</parameter>
+	<parameter name="family" unique="0" required="0">
+		<getopt mixed="-f, --family" />
+		<content type="string" default="auto" />
+		<shortdesc lang="en">Network family</shortdesc>
+	</parameter>
+	<parameter name="action" unique="0" required="0">
+		<getopt mixed="-o, --action" />
+		<content type="string" default="off" />
+		<shortdesc lang="en">Fencing action</shortdesc>
+	</parameter>
+	<parameter name="timeout" unique="0" required="0">
+		<getopt mixed="-t, --timeout" />
+		<content type="string" default="60" />
+		<shortdesc lang="en">Timeout in seconds</shortdesc>
+	</parameter>
+	<parameter name="verbose" unique="0" required="0">
+		<getopt mixed="-v, --verbose" />
+		<content type="boolean" />
+		<shortdesc lang="en">Print verbose output</shortdesc>
+	</parameter>
+	<parameter name="version" unique="0" required="0">
+		<getopt mixed="-V, --version" />
+		<content type="boolean" />
+		<shortdesc lang="en">Print version</shortdesc>
+	</parameter>
+	<parameter name="usage" unique="0" required="0">
+		<getopt mixed="-h, --help" />
+		<content type="boolean" />
+		<shortdesc lang="en">Print usage</shortdesc>
+	</parameter>
+</parameters>
+<actions>
+	<action name="off" />
+	<action name="monitor" />
+	<action name="metadata" />
+</actions>
+</resource-agent>
diff --git a/tests/data/metadata/fence_ldom.xml b/tests/data/metadata/fence_ldom.xml
new file mode 100644
index 0000000..df8897c
--- /dev/null
+++ b/tests/data/metadata/fence_ldom.xml
@@ -0,0 +1,145 @@
+<?xml version="1.0" ?>
+<resource-agent name="fence_ldom" shortdesc="Fence agent for Sun LDOM" >
+<longdesc>fence_ldom is an I/O Fencing agent which can be used with LDoms virtual machines. This agent works so, that run ldm command on host machine. So ldm must be directly runnable.
+.P
+Very useful parameter is -c (or cmd_prompt in stdin mode). This must be set to something, what is displayed after successful login to host machine. Default string is space on end of string (default for root in bash). But (for example) csh use ], so in that case you must use parameter -c with argument ]. Very similar situation is, if you use bash and login to host machine with other user than root. Than prompt is $, so again, you must use parameter -c.</longdesc>
+<vendor-url>http://www.sun.com</vendor-url>
+<parameters>
+	<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="cmd_prompt" unique="0" required="0">
+		<getopt mixed="-c, --command-prompt=[prompt]" />
+		<content type="string" default="['\\ $']"  />
+		<shortdesc lang="en">Force Python regex for command prompt</shortdesc>
+	</parameter>
+	<parameter name="identity_file" unique="0" required="0">
+		<getopt mixed="-k, --identity-file=[filename]" />
+		<content type="string"  />
+		<shortdesc lang="en">Identity file for ssh</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="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</shortdesc>
+	</parameter>
+	<parameter name="ipport" unique="0" required="0">
+		<getopt mixed="-u, --ipport=[port]" />
+		<content type="string" default="22"  />
+		<shortdesc lang="en">TCP/UDP port to use for connection with device</shortdesc>
+	</parameter>
+	<parameter name="login" unique="0" required="1">
+		<getopt mixed="-l, --username=[name]" />
+		<content type="string"  />
+		<shortdesc lang="en">Login Name</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="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="port" unique="0" required="1">
+		<getopt mixed="-n, --plug=[id]" />
+		<content type="string"  />
+		<shortdesc lang="en">Physical plug number, name of virtual machine or UUID</shortdesc>
+	</parameter>
+	<parameter name="secure" unique="0" required="0">
+		<getopt mixed="-x, --ssh" />
+		<content type="boolean" default="1"  />
+		<shortdesc lang="en">SSH connection</shortdesc>
+	</parameter>
+	<parameter name="ssh_options" unique="0" required="0">
+		<getopt mixed="--ssh-options=[options]" />
+		<content type="string"  />
+		<shortdesc lang="en">SSH options to use</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="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="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="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="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>
+	<parameter name="ssh_path" unique="0" required="0">
+		<getopt mixed="--ssh-path=[path]" />
+		<content type="string" default="/usr/bin/ssh"  />
+		<shortdesc lang="en">Path to ssh binary</shortdesc>
+	</parameter>
+</parameters>
+<actions>
+	<action name="on" automatic="0"/>
+	<action name="off" />
+	<action name="reboot" />
+	<action name="status" />
+	<action name="list" />
+	<action name="list-status" />
+	<action name="monitor" />
+	<action name="metadata" />
+	<action name="validate-all" />
+</actions>
+</resource-agent>
diff --git a/tests/data/metadata/fence_lpar.xml b/tests/data/metadata/fence_lpar.xml
new file mode 100644
index 0000000..967815e
--- /dev/null
+++ b/tests/data/metadata/fence_lpar.xml
@@ -0,0 +1,156 @@
+<?xml version="1.0" ?>
+<resource-agent name="fence_lpar" shortdesc="Fence agent for IBM LPAR" >
+<longdesc></longdesc>
+<vendor-url>http://www.ibm.com</vendor-url>
+<parameters>
+	<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="cmd_prompt" unique="0" required="0">
+		<getopt mixed="-c, --command-prompt=[prompt]" />
+		<content type="string" default="[':~>', ']\\$', '\\$ ']"  />
+		<shortdesc lang="en">Force Python regex for command prompt</shortdesc>
+	</parameter>
+	<parameter name="hmc_version" unique="0" required="0">
+		<getopt mixed="-H, --hmc-version=[version]" />
+		<content type="select" default="4"  >
+			<option value="3" />
+			<option value="4" />
+		</content>
+		<shortdesc lang="en">Force HMC version to use (3 or 4)</shortdesc>
+	</parameter>
+	<parameter name="identity_file" unique="0" required="0">
+		<getopt mixed="-k, --identity-file=[filename]" />
+		<content type="string"  />
+		<shortdesc lang="en">Identity file for ssh</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="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</shortdesc>
+	</parameter>
+	<parameter name="ipport" unique="0" required="0">
+		<getopt mixed="-u, --ipport=[port]" />
+		<content type="string" default="22"  />
+		<shortdesc lang="en">TCP/UDP port to use for connection with device</shortdesc>
+	</parameter>
+	<parameter name="login" unique="0" required="1">
+		<getopt mixed="-l, --username=[name]" />
+		<content type="string"  />
+		<shortdesc lang="en">Login Name</shortdesc>
+	</parameter>
+	<parameter name="managed" unique="0" required="0">
+		<getopt mixed="-s, --managed=[id]" />
+		<content type="string"  />
+		<shortdesc lang="en">Managed system name</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="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="port" unique="0" required="1">
+		<getopt mixed="-n, --plug=[id]" />
+		<content type="string"  />
+		<shortdesc lang="en">Physical plug number, name of virtual machine or UUID</shortdesc>
+	</parameter>
+	<parameter name="secure" unique="0" required="0">
+		<getopt mixed="-x, --ssh" />
+		<content type="boolean" default="1"  />
+		<shortdesc lang="en">SSH connection</shortdesc>
+	</parameter>
+	<parameter name="ssh_options" unique="0" required="0">
+		<getopt mixed="--ssh-options=[options]" />
+		<content type="string"  />
+		<shortdesc lang="en">SSH options to use</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="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="login_timeout" unique="0" required="0">
+		<getopt mixed="--login-timeout=[seconds]" />
+		<content type="string" default="15"  />
+		<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="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="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>
+	<parameter name="ssh_path" unique="0" required="0">
+		<getopt mixed="--ssh-path=[path]" />
+		<content type="string" default="/usr/bin/ssh"  />
+		<shortdesc lang="en">Path to ssh binary</shortdesc>
+	</parameter>
+</parameters>
+<actions>
+	<action name="on" automatic="0"/>
+	<action name="off" />
+	<action name="reboot" />
+	<action name="status" />
+	<action name="list" />
+	<action name="list-status" />
+	<action name="monitor" />
+	<action name="metadata" />
+	<action name="validate-all" />
+</actions>
+</resource-agent>
diff --git a/tests/data/metadata/fence_mpath.xml b/tests/data/metadata/fence_mpath.xml
new file mode 100644
index 0000000..c805331
--- /dev/null
+++ b/tests/data/metadata/fence_mpath.xml
@@ -0,0 +1,100 @@
+<?xml version="1.0" ?>
+<resource-agent name="fence_mpath" shortdesc="Fence agent for multipath persistent reservation" >
+<longdesc>fence_mpath is an I/O fencing agent that uses SCSI-3 persistent reservations to control access multipath devices. Underlying devices must support SCSI-3 persistent reservations (SPC-3 or greater) as well as the "preempt-and-abort" subcommand.
+The fence_mpath agent works by having an unique key for each pair of node and device that has to be set also in /etc/multipath.conf. Once registered, a single node will become the reservation holder by creating a "write exclusive, registrants only" reservation on the device(s). The result is that only registered nodes may write to the device(s). When a node failure occurs, the fence_mpath agent will remove the key belonging to the failed node from the device(s). The failed node will no l [...]
+<vendor-url>https://www.sourceware.org/dm/</vendor-url>
+<parameters>
+	<parameter name="action" unique="0" required="1">
+		<getopt mixed="-o, --action=[action]" />
+		<content type="string" default="off"  />
+		<shortdesc lang="en">Fencing Action</shortdesc>
+	</parameter>
+	<parameter name="devices" unique="0" required="0">
+		<getopt mixed="-d, --devices=[devices]" />
+		<content type="string"  />
+		<shortdesc lang="en">List of devices to use for current operation. Devices can be comma-separated list of device-mapper multipath devices (eg. /dev/dm-3). Each device must support SCSI-3 persistent reservations.</shortdesc>
+	</parameter>
+	<parameter name="key" unique="0" required="1">
+		<getopt mixed="-k, --key=[key]" />
+		<content type="string"  />
+		<shortdesc lang="en">Key to use for the current operation. This key should be unique to a node and have to be written in /etc/multipath.conf. For the "on" action, the key specifies the key use to register the local node. For the "off" action, this key specifies the key to be removed from the device(s).</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="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="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="mpathpersist_path" unique="0" required="0">
+		<getopt mixed="--mpathpersist-path=[path]" />
+		<content type="string" default="/usr/sbin/mpathpersist"  />
+		<shortdesc lang="en">Path to mpathpersist binary</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="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="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="store_path" unique="0" required="0">
+		<getopt mixed="--store-path=[path]" />
+		<shortdesc lang="en">Path to directory where fence agent can store information</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>
+	<parameter name="sudo" unique="0" required="0">
+		<getopt mixed="--use-sudo" />
+		<content type="boolean"  />
+		<shortdesc lang="en">Use sudo (without password) when calling 3rd party sotfware.</shortdesc>
+	</parameter>
+	<parameter name="sudo_path" unique="0" required="0">
+		<getopt mixed="--sudo-path=[path]" />
+		<content type="string" default="/usr/bin/sudo"  />
+		<shortdesc lang="en">Path to sudo binary</shortdesc>
+	</parameter>
+</parameters>
+<actions>
+	<action name="on" on_target="1" automatic="1"/>
+	<action name="off" />
+	<action name="status" />
+	<action name="monitor" />
+	<action name="metadata" />
+	<action name="validate-all" />
+</actions>
+</resource-agent>
diff --git a/tests/data/metadata/fence_netio.xml b/tests/data/metadata/fence_netio.xml
new file mode 100644
index 0000000..bcaac43
--- /dev/null
+++ b/tests/data/metadata/fence_netio.xml
@@ -0,0 +1,123 @@
+<?xml version="1.0" ?>
+<resource-agent name="fence_netio" shortdesc="I/O Fencing agent for Koukaam NETIO-230B" >
+<longdesc>fence_netio is an I/O Fencing agent which can be used with the Koukaam NETIO-230B Power Distribution Unit. It logs into device via telnet and reboots a specified outlet. Lengthy telnet connections should be avoided while a GFS cluster is running because the connection will block any necessary fencing actions.</longdesc>
+<vendor-url>http://www.koukaam.se/</vendor-url>
+<parameters>
+	<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="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="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</shortdesc>
+	</parameter>
+	<parameter name="ipport" unique="0" required="0">
+		<getopt mixed="-u, --ipport=[port]" />
+		<content type="string" default="1234"  />
+		<shortdesc lang="en">TCP/UDP port to use for connection with device</shortdesc>
+	</parameter>
+	<parameter name="login" unique="0" required="1">
+		<getopt mixed="-l, --username=[name]" />
+		<content type="string"  />
+		<shortdesc lang="en">Login Name</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="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="port" unique="0" required="1">
+		<getopt mixed="-n, --plug=[id]" />
+		<content type="string"  />
+		<shortdesc lang="en">Physical plug number, name of virtual machine or UUID</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="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="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="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="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>
+	<parameter name="telnet_path" unique="0" required="0">
+		<getopt mixed="--telnet-path=[path]" />
+		<content type="string" default="/usr/bin/telnet"  />
+		<shortdesc lang="en">Path to telnet binary</shortdesc>
+	</parameter>
+</parameters>
+<actions>
+	<action name="on" automatic="0"/>
+	<action name="off" />
+	<action name="reboot" />
+	<action name="status" />
+	<action name="list" />
+	<action name="list-status" />
+	<action name="monitor" />
+	<action name="metadata" />
+	<action name="validate-all" />
+</actions>
+</resource-agent>
diff --git a/tests/data/metadata/fence_ovh.xml b/tests/data/metadata/fence_ovh.xml
new file mode 100644
index 0000000..19df958
--- /dev/null
+++ b/tests/data/metadata/fence_ovh.xml
@@ -0,0 +1,102 @@
+<?xml version="1.0" ?>
+<resource-agent name="fence_ovh" shortdesc="Fence agent for OVH" >
+<longdesc>fence_ovh is an Power Fencing agent which can be used within OVH datecentre. Poweroff is simulated with a reboot into rescue-pro mode.</longdesc>
+<vendor-url>http://www.ovh.net</vendor-url>
+<parameters>
+	<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="email" unique="0" required="1">
+		<getopt mixed="-Z, --email=[email]" />
+		<content type="string"  />
+		<shortdesc lang="en">Reboot email</shortdesc>
+	</parameter>
+	<parameter name="login" unique="0" required="1">
+		<getopt mixed="-l, --username=[name]" />
+		<content type="string"  />
+		<shortdesc lang="en">Login Name</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="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="port" unique="0" required="1">
+		<getopt mixed="-n, --plug=[id]" />
+		<content type="string"  />
+		<shortdesc lang="en">Physical plug number, name of virtual machine or UUID</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="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="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="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="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="list" />
+	<action name="list-status" />
+	<action name="monitor" />
+	<action name="metadata" />
+	<action name="validate-all" />
+</actions>
+</resource-agent>
diff --git a/tests/data/metadata/fence_pve.xml b/tests/data/metadata/fence_pve.xml
new file mode 100644
index 0000000..838f12c
--- /dev/null
+++ b/tests/data/metadata/fence_pve.xml
@@ -0,0 +1,123 @@
+<?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="action" unique="0" required="1">
+		<getopt mixed="-o, --action=[action]" />
+		<content type="string" default="reboot"  />
+		<shortdesc lang="en">Fencing Action</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="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="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="login" unique="0" required="1">
+		<getopt mixed="-l, --username=[name]" />
+		<content type="string" default="root at pam"  />
+		<shortdesc lang="en">Login Name</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="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="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="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="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="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="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="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="list-status" />
+	<action name="monitor" />
+	<action name="metadata" />
+	<action name="validate-all" />
+</actions>
+</resource-agent>
diff --git a/tests/data/metadata/fence_raritan.xml b/tests/data/metadata/fence_raritan.xml
new file mode 100644
index 0000000..d66fd55
--- /dev/null
+++ b/tests/data/metadata/fence_raritan.xml
@@ -0,0 +1,123 @@
+<?xml version="1.0" ?>
+<resource-agent name="fence_raritan" shortdesc="I/O Fencing agent for Raritan Dominion PX" >
+<longdesc>fence_raritan is an I/O Fencing agent which can be used with the Raritan DPXS12-20 Power Distribution Unit. It logs into device via telnet and reboots a specified outlet. Lengthy telnet connections should be avoided while a GFS cluster is running because the connection will block any necessary fencing actions.</longdesc>
+<vendor-url>http://www.raritan.com/</vendor-url>
+<parameters>
+	<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="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="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</shortdesc>
+	</parameter>
+	<parameter name="ipport" unique="0" required="0">
+		<getopt mixed="-u, --ipport=[port]" />
+		<content type="string" default="23"  />
+		<shortdesc lang="en">TCP/UDP port to use for connection with device</shortdesc>
+	</parameter>
+	<parameter name="login" unique="0" required="1">
+		<getopt mixed="-l, --username=[name]" />
+		<content type="string"  />
+		<shortdesc lang="en">Login Name</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="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="port" unique="0" required="1">
+		<getopt mixed="-n, --plug=[id]" />
+		<content type="string"  />
+		<shortdesc lang="en">Physical plug number, name of virtual machine or UUID</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="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="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="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="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>
+	<parameter name="telnet_path" unique="0" required="0">
+		<getopt mixed="--telnet-path=[path]" />
+		<content type="string" default="/usr/bin/telnet"  />
+		<shortdesc lang="en">Path to telnet binary</shortdesc>
+	</parameter>
+</parameters>
+<actions>
+	<action name="on" automatic="0"/>
+	<action name="off" />
+	<action name="reboot" />
+	<action name="status" />
+	<action name="list" />
+	<action name="list-status" />
+	<action name="monitor" />
+	<action name="metadata" />
+	<action name="validate-all" />
+</actions>
+</resource-agent>
diff --git a/tests/data/metadata/fence_rhevm.xml b/tests/data/metadata/fence_rhevm.xml
new file mode 100644
index 0000000..87f90ed
--- /dev/null
+++ b/tests/data/metadata/fence_rhevm.xml
@@ -0,0 +1,148 @@
+<?xml version="1.0" ?>
+<resource-agent name="fence_rhevm" shortdesc="Fence agent for RHEV-M REST API" >
+<longdesc>fence_rhevm is an I/O Fencing agent which can be used with RHEV-M REST API to fence virtual machines.</longdesc>
+<vendor-url>http://www.redhat.com</vendor-url>
+<parameters>
+	<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="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="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</shortdesc>
+	</parameter>
+	<parameter name="ipport" unique="0" required="0">
+		<getopt mixed="-u, --ipport=[port]" />
+		<content type="string" default="80"  />
+		<shortdesc lang="en">TCP/UDP port to use for connection with device</shortdesc>
+	</parameter>
+	<parameter name="login" unique="0" required="1">
+		<getopt mixed="-l, --username=[name]" />
+		<content type="string"  />
+		<shortdesc lang="en">Login Name</shortdesc>
+	</parameter>
+	<parameter name="notls" unique="0" required="0">
+		<getopt mixed="-t, --notls" />
+		<content type="boolean"  />
+		<shortdesc lang="en">Disable TLS negotiation, force SSL 3.0</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="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="port" unique="0" required="1">
+		<getopt mixed="-n, --plug=[id]" />
+		<content type="string"  />
+		<shortdesc lang="en">Physical plug number, name of virtual machine or UUID</shortdesc>
+	</parameter>
+	<parameter name="ssl" unique="0" required="0">
+		<getopt mixed="-z, --ssl" />
+		<content type="boolean"  />
+		<shortdesc lang="en">SSL connection</shortdesc>
+	</parameter>
+	<parameter name="ssl_insecure" unique="0" required="0">
+		<getopt mixed="--ssl-insecure" />
+		<content type="boolean"  />
+		<shortdesc lang="en">SSL connection without verifying fence device's certificate</shortdesc>
+	</parameter>
+	<parameter name="ssl_secure" unique="0" required="0">
+		<getopt mixed="--ssl-secure" />
+		<content type="boolean"  />
+		<shortdesc lang="en">SSL connection with verifying fence device's certificate</shortdesc>
+	</parameter>
+	<parameter name="use_cookies" unique="0" required="0">
+		<getopt mixed="--use-cookies" />
+		<content type="boolean"  />
+		<shortdesc lang="en">Reuse cookies for authentication</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="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="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="power_wait" unique="0" required="0">
+		<getopt mixed="--power-wait=[seconds]" />
+		<content type="string" default="1"  />
+		<shortdesc lang="en">Wait X seconds after issuing ON/OFF</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>
+	<parameter name="gnutlscli_path" unique="0" required="0">
+		<getopt mixed="--gnutlscli-path=[path]" />
+		<content type="string" default="/usr/bin/gnutls-cli"  />
+		<shortdesc lang="en">Path to gnutls-cli binary</shortdesc>
+	</parameter>
+</parameters>
+<actions>
+	<action name="on" automatic="0"/>
+	<action name="off" />
+	<action name="reboot" />
+	<action name="status" />
+	<action name="list" />
+	<action name="list-status" />
+	<action name="monitor" />
+	<action name="metadata" />
+	<action name="validate-all" />
+</actions>
+</resource-agent>
diff --git a/tests/data/metadata/fence_rsa.xml b/tests/data/metadata/fence_rsa.xml
new file mode 100644
index 0000000..de2ef23
--- /dev/null
+++ b/tests/data/metadata/fence_rsa.xml
@@ -0,0 +1,136 @@
+<?xml version="1.0" ?>
+<resource-agent name="fence_rsa" shortdesc="Fence agent for IBM RSA" >
+<longdesc>fence_rsa is an I/O Fencing agent which can be used with the IBM RSA II management interface. It logs into an RSA II device via telnet and reboots the associated machine. Lengthy telnet connections to the RSA II device should be avoided while a GFS cluster is running because the connection will block any necessary fencing actions.</longdesc>
+<vendor-url>http://www.ibm.com</vendor-url>
+<parameters>
+	<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="cmd_prompt" unique="0" required="0">
+		<getopt mixed="-c, --command-prompt=[prompt]" />
+		<content type="string" default="['>']"  />
+		<shortdesc lang="en">Force Python regex for command prompt</shortdesc>
+	</parameter>
+	<parameter name="identity_file" unique="0" required="0">
+		<getopt mixed="-k, --identity-file=[filename]" />
+		<content type="string"  />
+		<shortdesc lang="en">Identity file for ssh</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="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</shortdesc>
+	</parameter>
+	<parameter name="ipport" unique="0" required="0">
+		<getopt mixed="-u, --ipport=[port]" />
+		<content type="string" default="23"  />
+		<shortdesc lang="en">TCP/UDP port to use for connection with device</shortdesc>
+	</parameter>
+	<parameter name="login" unique="0" required="1">
+		<getopt mixed="-l, --username=[name]" />
+		<content type="string"  />
+		<shortdesc lang="en">Login Name</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="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="secure" unique="0" required="0">
+		<getopt mixed="-x, --ssh" />
+		<content type="boolean"  />
+		<shortdesc lang="en">SSH connection</shortdesc>
+	</parameter>
+	<parameter name="ssh_options" unique="0" required="0">
+		<getopt mixed="--ssh-options=[options]" />
+		<content type="string" default="-F /dev/null"  />
+		<shortdesc lang="en">SSH options to use</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="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="login_timeout" unique="0" required="0">
+		<getopt mixed="--login-timeout=[seconds]" />
+		<content type="string" default="10"  />
+		<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="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="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>
+	<parameter name="ssh_path" unique="0" required="0">
+		<getopt mixed="--ssh-path=[path]" />
+		<content type="string" default="/usr/bin/ssh"  />
+		<shortdesc lang="en">Path to ssh binary</shortdesc>
+	</parameter>
+	<parameter name="telnet_path" unique="0" required="0">
+		<getopt mixed="--telnet-path=[path]" />
+		<content type="string" default="/usr/bin/telnet"  />
+		<shortdesc lang="en">Path to telnet binary</shortdesc>
+	</parameter>
+</parameters>
+<actions>
+	<action name="on" automatic="0"/>
+	<action name="off" />
+	<action name="reboot" />
+	<action name="status" />
+	<action name="monitor" />
+	<action name="metadata" />
+	<action name="validate-all" />
+</actions>
+</resource-agent>
diff --git a/tests/data/metadata/fence_rsb.xml b/tests/data/metadata/fence_rsb.xml
new file mode 100644
index 0000000..ff4450e
--- /dev/null
+++ b/tests/data/metadata/fence_rsb.xml
@@ -0,0 +1,136 @@
+<?xml version="1.0" ?>
+<resource-agent name="fence_rsb" shortdesc="I/O Fencing agent for Fujitsu-Siemens RSB" >
+<longdesc>fence_rsb is an I/O Fencing agent which can be used with the Fujitsu-Siemens RSB management interface. It logs into device via telnet/ssh  and reboots a specified outlet. Lengthy telnet/ssh connections should be avoided while a GFS cluster is running because the connection will block any necessary fencing actions.</longdesc>
+<vendor-url>http://www.fujitsu.com</vendor-url>
+<parameters>
+	<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="cmd_prompt" unique="0" required="0">
+		<getopt mixed="-c, --command-prompt=[prompt]" />
+		<content type="string" default="['to quit:']"  />
+		<shortdesc lang="en">Force Python regex for command prompt</shortdesc>
+	</parameter>
+	<parameter name="identity_file" unique="0" required="0">
+		<getopt mixed="-k, --identity-file=[filename]" />
+		<content type="string"  />
+		<shortdesc lang="en">Identity file for ssh</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="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</shortdesc>
+	</parameter>
+	<parameter name="ipport" unique="0" required="0">
+		<getopt mixed="-u, --ipport=[port]" />
+		<content type="string" default="3172"  />
+		<shortdesc lang="en">TCP/UDP port to use for connection with device</shortdesc>
+	</parameter>
+	<parameter name="login" unique="0" required="1">
+		<getopt mixed="-l, --username=[name]" />
+		<content type="string"  />
+		<shortdesc lang="en">Login Name</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="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="secure" unique="0" required="0">
+		<getopt mixed="-x, --ssh" />
+		<content type="boolean"  />
+		<shortdesc lang="en">SSH connection</shortdesc>
+	</parameter>
+	<parameter name="ssh_options" unique="0" required="0">
+		<getopt mixed="--ssh-options=[options]" />
+		<content type="string"  />
+		<shortdesc lang="en">SSH options to use</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="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="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="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="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>
+	<parameter name="ssh_path" unique="0" required="0">
+		<getopt mixed="--ssh-path=[path]" />
+		<content type="string" default="/usr/bin/ssh"  />
+		<shortdesc lang="en">Path to ssh binary</shortdesc>
+	</parameter>
+	<parameter name="telnet_path" unique="0" required="0">
+		<getopt mixed="--telnet-path=[path]" />
+		<content type="string" default="/usr/bin/telnet"  />
+		<shortdesc lang="en">Path to telnet binary</shortdesc>
+	</parameter>
+</parameters>
+<actions>
+	<action name="on" automatic="0"/>
+	<action name="off" />
+	<action name="reboot" />
+	<action name="status" />
+	<action name="monitor" />
+	<action name="metadata" />
+	<action name="validate-all" />
+</actions>
+</resource-agent>
diff --git a/tests/data/metadata/fence_sanbox2.xml b/tests/data/metadata/fence_sanbox2.xml
new file mode 100644
index 0000000..18e7c31
--- /dev/null
+++ b/tests/data/metadata/fence_sanbox2.xml
@@ -0,0 +1,127 @@
+<?xml version="1.0" ?>
+<resource-agent name="fence_sanbox2" shortdesc="Fence agent for QLogic SANBox2 FC switches" >
+<longdesc>fence_sanbox2 is an I/O Fencing agent which can be used with QLogic SANBox2 FC switches.  It logs into a SANBox2 switch via telnet and disables a specified port. Disabling  the port which a machine is connected to effectively fences that machine. Lengthy telnet connections to the switch should be avoided while a GFS cluster is running because the connection will block any necessary fencing actions.</longdesc>
+<vendor-url>http://www.qlogic.com</vendor-url>
+<parameters>
+	<parameter name="action" unique="0" required="1">
+		<getopt mixed="-o, --action=[action]" />
+		<content type="string" default="off"  />
+		<shortdesc lang="en">Fencing Action</shortdesc>
+	</parameter>
+	<parameter name="cmd_prompt" unique="0" required="0">
+		<getopt mixed="-c, --command-prompt=[prompt]" />
+		<content type="string" default="[' #> ']"  />
+		<shortdesc lang="en">Force Python regex for command prompt</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="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</shortdesc>
+	</parameter>
+	<parameter name="ipport" unique="0" required="0">
+		<getopt mixed="-u, --ipport=[port]" />
+		<content type="string" default="23"  />
+		<shortdesc lang="en">TCP/UDP port to use for connection with device</shortdesc>
+	</parameter>
+	<parameter name="login" unique="0" required="1">
+		<getopt mixed="-l, --username=[name]" />
+		<content type="string"  />
+		<shortdesc lang="en">Login Name</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="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="port" unique="0" required="1">
+		<getopt mixed="-n, --plug=[id]" />
+		<content type="string"  />
+		<shortdesc lang="en">Physical plug number, name of virtual machine or UUID</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="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="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="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="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>
+	<parameter name="telnet_path" unique="0" required="0">
+		<getopt mixed="--telnet-path=[path]" />
+		<content type="string" default="/usr/bin/telnet"  />
+		<shortdesc lang="en">Path to telnet binary</shortdesc>
+	</parameter>
+</parameters>
+<actions>
+	<action name="on" automatic="1"/>
+	<action name="off" />
+	<action name="status" />
+	<action name="list" />
+	<action name="list-status" />
+	<action name="monitor" />
+	<action name="metadata" />
+	<action name="validate-all" />
+</actions>
+</resource-agent>
diff --git a/tests/data/metadata/fence_scsi.xml b/tests/data/metadata/fence_scsi.xml
new file mode 100644
index 0000000..01e5648
--- /dev/null
+++ b/tests/data/metadata/fence_scsi.xml
@@ -0,0 +1,116 @@
+<?xml version="1.0" ?>
+<resource-agent name="fence_scsi" shortdesc="Fence agent for SCSI persistentl reservation" >
+<longdesc>fence_scsi is an I/O fencing agent that uses SCSI-3 persistent reservations to control access to shared storage devices. These devices must support SCSI-3 persistent reservations (SPC-3 or greater) as well as the "preempt-and-abort" subcommand.
+The fence_scsi agent works by having each node in the cluster register a unique key with the SCSI devive(s). Once registered, a single node will become the reservation holder by creating a "write exclusive, registrants only" reservation on the device(s). The result is that only registered nodes may write to the device(s). When a node failure occurs, the fence_scsi agent will remove the key belonging to the failed node from the device(s). The failed node will no longer be able to write to [...]
+<vendor-url></vendor-url>
+<parameters>
+	<parameter name="action" unique="0" required="1">
+		<getopt mixed="-o, --action=[action]" />
+		<content type="string" default="off"  />
+		<shortdesc lang="en">Fencing Action</shortdesc>
+	</parameter>
+	<parameter name="aptpl" unique="0" required="0">
+		<getopt mixed="-a, --aptpl" />
+		<content type="boolean"  />
+		<shortdesc lang="en">Use the APTPL flag for registrations. This option is only used for the 'on' action.</shortdesc>
+	</parameter>
+	<parameter name="devices" unique="0" required="0">
+		<getopt mixed="-d, --devices=[devices]" />
+		<content type="string"  />
+		<shortdesc lang="en">List of devices to use for current operation. Devices can be comma-separated list of raw device (eg. /dev/sdc) or device-mapper multipath devices (eg. /dev/dm-3). Each device must support SCSI-3 persistent reservations.</shortdesc>
+	</parameter>
+	<parameter name="key" unique="0" required="0">
+		<getopt mixed="-k, --key=[key]" />
+		<content type="string"  />
+		<shortdesc lang="en">Key to use for the current operation. This key should be unique to a node. For the "on" action, the key specifies the key use to register the local node. For the "off" action, this key specifies the key to be removed from the device(s).</shortdesc>
+	</parameter>
+	<parameter name="nodename" unique="0" required="0">
+		<getopt mixed="-n, --nodename=[nodename]" />
+		<content type="string"  />
+		<shortdesc lang="en">Name of the node to be fenced. The node name is used to generate the key value used for the current operation. This option will be ignored when used with the -k option.</shortdesc>
+	</parameter>
+	<parameter name="logfile" unique="0" required="0">
+		<getopt mixed="-f, --logfile" />
+		<content type="string"  />
+		<shortdesc lang="en">Log output (stdout and stderr) to file</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="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="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="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="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>
+	<parameter name="corosync-cmap_path" unique="0" required="0">
+		<getopt mixed="--corosync-cmap-path=[path]" />
+		<content type="string" default="/usr/sbin/corosync-cmapctl"  />
+		<shortdesc lang="en">Path to corosync-cmapctl binary</shortdesc>
+	</parameter>
+	<parameter name="sg_persist_path" unique="0" required="0">
+		<getopt mixed="--sg_persist-path=[path]" />
+		<content type="string" default="/usr/bin/sg_persist"  />
+		<shortdesc lang="en">Path to sg_persist binary</shortdesc>
+	</parameter>
+	<parameter name="sg_turs_path" unique="0" required="0">
+		<getopt mixed="--sg_turs-path=[path]" />
+		<content type="string" default="/usr/bin/sg_turs"  />
+		<shortdesc lang="en">Path to sg_turs binary</shortdesc>
+	</parameter>
+	<parameter name="vgs_path" unique="0" required="0">
+		<getopt mixed="--vgs-path=[path]" />
+		<content type="string" default="/usr/sbin/vgs"  />
+		<shortdesc lang="en">Path to vgs binary</shortdesc>
+	</parameter>
+</parameters>
+<actions>
+	<action name="on" on_target="1" automatic="1"/>
+	<action name="off" />
+	<action name="status" />
+	<action name="monitor" />
+	<action name="metadata" />
+	<action name="validate-all" />
+</actions>
+</resource-agent>
diff --git a/tests/data/metadata/fence_tripplite_snmp.xml b/tests/data/metadata/fence_tripplite_snmp.xml
new file mode 100644
index 0000000..fc98bd4
--- /dev/null
+++ b/tests/data/metadata/fence_tripplite_snmp.xml
@@ -0,0 +1,182 @@
+<?xml version="1.0" ?>
+<resource-agent name="fence_tripplite_snmp" shortdesc="Fence agent for APC, Tripplite PDU over SNMP" >
+<longdesc>fence_apc_snmp is an I/O Fencing agent which can be used with the APC network power switch or Tripplite PDU devices.It logs into a device via SNMP and reboots a specified outlet. It supports SNMP v1, v2c, v3 with all combinations of  authenticity/privacy settings.</longdesc>
+<vendor-url>http://www.apc.com</vendor-url>
+<parameters>
+	<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="community" unique="0" required="0">
+		<getopt mixed="-c, --community=[community]" />
+		<content type="string" default="private"  />
+		<shortdesc lang="en">Set the community string</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="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</shortdesc>
+	</parameter>
+	<parameter name="ipport" unique="0" required="0">
+		<getopt mixed="-u, --ipport=[port]" />
+		<content type="string" default="161"  />
+		<shortdesc lang="en">TCP/UDP port to use for connection with device</shortdesc>
+	</parameter>
+	<parameter name="login" unique="0" required="0">
+		<getopt mixed="-l, --username=[name]" />
+		<content type="string"  />
+		<shortdesc lang="en">Login Name</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="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="port" unique="0" required="1">
+		<getopt mixed="-n, --plug=[id]" />
+		<content type="string"  />
+		<shortdesc lang="en">Physical plug number, name of virtual machine or UUID</shortdesc>
+	</parameter>
+	<parameter name="snmp_auth_prot" unique="0" required="0">
+		<getopt mixed="-b, --snmp-auth-prot=[prot]" />
+		<content type="select"  >
+			<option value="MD5" />
+			<option value="SHA" />
+		</content>
+		<shortdesc lang="en">Set authentication protocol (MD5|SHA)</shortdesc>
+	</parameter>
+	<parameter name="snmp_priv_passwd" unique="0" required="0">
+		<getopt mixed="-P, --snmp-priv-passwd=[pass]" />
+		<content type="string"  />
+		<shortdesc lang="en">Set privacy protocol password</shortdesc>
+	</parameter>
+	<parameter name="snmp_priv_passwd_script" unique="0" required="0">
+		<getopt mixed="-R, --snmp-priv-passwd-script" />
+		<content type="string"  />
+		<shortdesc lang="en">Script to run to retrieve privacy password</shortdesc>
+	</parameter>
+	<parameter name="snmp_priv_prot" unique="0" required="0">
+		<getopt mixed="-B, --snmp-priv-prot=[prot]" />
+		<content type="select"  >
+			<option value="DES" />
+			<option value="AES" />
+		</content>
+		<shortdesc lang="en">Set privacy protocol (DES|AES)</shortdesc>
+	</parameter>
+	<parameter name="snmp_sec_level" unique="0" required="0">
+		<getopt mixed="-E, --snmp-sec-level=[level]" />
+		<content type="select"  >
+			<option value="noAuthNoPriv" />
+			<option value="authNoPriv" />
+			<option value="authPriv" />
+		</content>
+		<shortdesc lang="en">Set security level (noAuthNoPriv|authNoPriv|authPriv)</shortdesc>
+	</parameter>
+	<parameter name="snmp_version" unique="0" required="0">
+		<getopt mixed="-d, --snmp-version=[version]" />
+		<content type="select" default="1"  >
+			<option value="1" />
+			<option value="2c" />
+			<option value="3" />
+		</content>
+		<shortdesc lang="en">Specifies SNMP version to use (1,2c,3)</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="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="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="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="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>
+	<parameter name="snmpget_path" unique="0" required="0">
+		<getopt mixed="--snmpget-path=[path]" />
+		<content type="string" default="/usr/bin/snmpget"  />
+		<shortdesc lang="en">Path to snmpget binary</shortdesc>
+	</parameter>
+	<parameter name="snmpset_path" unique="0" required="0">
+		<getopt mixed="--snmpset-path=[path]" />
+		<content type="string" default="/usr/bin/snmpset"  />
+		<shortdesc lang="en">Path to snmpset binary</shortdesc>
+	</parameter>
+	<parameter name="snmpwalk_path" unique="0" required="0">
+		<getopt mixed="--snmpwalk-path=[path]" />
+		<content type="string" default="/usr/bin/snmpwalk"  />
+		<shortdesc lang="en">Path to snmpwalk binary</shortdesc>
+	</parameter>
+</parameters>
+<actions>
+	<action name="on" automatic="0"/>
+	<action name="off" />
+	<action name="reboot" />
+	<action name="status" />
+	<action name="list" />
+	<action name="list-status" />
+	<action name="monitor" />
+	<action name="metadata" />
+	<action name="validate-all" />
+</actions>
+</resource-agent>
diff --git a/tests/data/metadata/fence_virsh.xml b/tests/data/metadata/fence_virsh.xml
new file mode 100644
index 0000000..e03b2b9
--- /dev/null
+++ b/tests/data/metadata/fence_virsh.xml
@@ -0,0 +1,155 @@
+<?xml version="1.0" ?>
+<resource-agent name="fence_virsh" shortdesc="Fence agent for virsh" >
+<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. 
+.P
+By default, virsh needs root account to do properly work. So you must allow ssh login in your sshd_config.</longdesc>
+<vendor-url>http://libvirt.org</vendor-url>
+<parameters>
+	<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="cmd_prompt" unique="0" required="0">
+		<getopt mixed="-c, --command-prompt=[prompt]" />
+		<content type="string" default="['\\[EXPECT\\]#\\ ']"  />
+		<shortdesc lang="en">Force Python regex for command prompt</shortdesc>
+	</parameter>
+	<parameter name="identity_file" unique="0" required="0">
+		<getopt mixed="-k, --identity-file=[filename]" />
+		<content type="string"  />
+		<shortdesc lang="en">Identity file for ssh</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="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</shortdesc>
+	</parameter>
+	<parameter name="ipport" unique="0" required="0">
+		<getopt mixed="-u, --ipport=[port]" />
+		<content type="string" default="22"  />
+		<shortdesc lang="en">TCP/UDP port to use for connection with device</shortdesc>
+	</parameter>
+	<parameter name="login" unique="0" required="1">
+		<getopt mixed="-l, --username=[name]" />
+		<content type="string"  />
+		<shortdesc lang="en">Login Name</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="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="port" unique="0" required="1">
+		<getopt mixed="-n, --plug=[id]" />
+		<content type="string"  />
+		<shortdesc lang="en">Physical plug number, name of virtual machine or UUID</shortdesc>
+	</parameter>
+	<parameter name="secure" unique="0" required="0">
+		<getopt mixed="-x, --ssh" />
+		<content type="boolean" default="1"  />
+		<shortdesc lang="en">SSH connection</shortdesc>
+	</parameter>
+	<parameter name="ssh_options" unique="0" required="0">
+		<getopt mixed="--ssh-options=[options]" />
+		<content type="string" default="-t '/bin/bash -c "PS1=\[EXPECT\]#\  /bin/bash --noprofile --norc"'"  />
+		<shortdesc lang="en">SSH options to use</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="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="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="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="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>
+	<parameter name="sudo" unique="0" required="0">
+		<getopt mixed="--use-sudo" />
+		<content type="boolean"  />
+		<shortdesc lang="en">Use sudo (without password) when calling 3rd party sotfware.</shortdesc>
+	</parameter>
+	<parameter name="ssh_path" unique="0" required="0">
+		<getopt mixed="--ssh-path=[path]" />
+		<content type="string" default="/usr/bin/ssh"  />
+		<shortdesc lang="en">Path to ssh binary</shortdesc>
+	</parameter>
+	<parameter name="sudo_path" unique="0" required="0">
+		<getopt mixed="--sudo-path=[path]" />
+		<content type="string" default="/usr/bin/sudo"  />
+		<shortdesc lang="en">Path to sudo binary</shortdesc>
+	</parameter>
+</parameters>
+<actions>
+	<action name="on" automatic="0"/>
+	<action name="off" />
+	<action name="reboot" />
+	<action name="status" />
+	<action name="list" />
+	<action name="list-status" />
+	<action name="monitor" />
+	<action name="metadata" />
+	<action name="validate-all" />
+</actions>
+</resource-agent>
diff --git a/tests/data/metadata/fence_vmware_soap.xml b/tests/data/metadata/fence_vmware_soap.xml
new file mode 100644
index 0000000..accf864
--- /dev/null
+++ b/tests/data/metadata/fence_vmware_soap.xml
@@ -0,0 +1,145 @@
+<?xml version="1.0" ?>
+<resource-agent name="fence_vmware_soap" shortdesc="Fence agent for VMWare over SOAP API" >
+<longdesc>fence_vmware_soap is an I/O Fencing agent which can be used with the virtual machines managed by VMWare products that have SOAP API v4.1+. 
+.P
+Name of virtual machine (-n / port) has to be used in inventory path format (e.g. /datacenter/vm/Discovered virtual machine/myMachine). In the cases when name of yours VM is unique you can use it instead. Alternatively you can always use UUID to access virtual machine.</longdesc>
+<vendor-url>http://www.vmware.com</vendor-url>
+<parameters>
+	<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="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="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</shortdesc>
+	</parameter>
+	<parameter name="ipport" unique="0" required="0">
+		<getopt mixed="-u, --ipport=[port]" />
+		<content type="string" default="80"  />
+		<shortdesc lang="en">TCP/UDP port to use for connection with device</shortdesc>
+	</parameter>
+	<parameter name="login" unique="0" required="1">
+		<getopt mixed="-l, --username=[name]" />
+		<content type="string"  />
+		<shortdesc lang="en">Login Name</shortdesc>
+	</parameter>
+	<parameter name="notls" unique="0" required="0">
+		<getopt mixed="-t, --notls" />
+		<content type="boolean"  />
+		<shortdesc lang="en">Disable TLS negotiation, force SSL 3.0</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="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="port" unique="0" required="1">
+		<getopt mixed="-n, --plug=[id]" />
+		<content type="string"  />
+		<shortdesc lang="en">Physical plug number, name of virtual machine or UUID</shortdesc>
+	</parameter>
+	<parameter name="ssl" unique="0" required="0">
+		<getopt mixed="-z, --ssl" />
+		<content type="boolean"  />
+		<shortdesc lang="en">SSL connection</shortdesc>
+	</parameter>
+	<parameter name="ssl_insecure" unique="0" required="0">
+		<getopt mixed="--ssl-insecure" />
+		<content type="boolean"  />
+		<shortdesc lang="en">SSL connection without verifying fence device's certificate</shortdesc>
+	</parameter>
+	<parameter name="ssl_secure" unique="0" required="0">
+		<getopt mixed="--ssl-secure" />
+		<content type="boolean"  />
+		<shortdesc lang="en">SSL connection with verifying fence device's certificate</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="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="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="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="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>
+	<parameter name="gnutlscli_path" unique="0" required="0">
+		<getopt mixed="--gnutlscli-path=[path]" />
+		<content type="string" default="/usr/bin/gnutls-cli"  />
+		<shortdesc lang="en">Path to gnutls-cli binary</shortdesc>
+	</parameter>
+</parameters>
+<actions>
+	<action name="on" automatic="0"/>
+	<action name="off" />
+	<action name="reboot" />
+	<action name="status" />
+	<action name="list" />
+	<action name="list-status" />
+	<action name="monitor" />
+	<action name="metadata" />
+	<action name="validate-all" />
+</actions>
+</resource-agent>
diff --git a/tests/data/metadata/fence_wti.xml b/tests/data/metadata/fence_wti.xml
new file mode 100644
index 0000000..83d5f78
--- /dev/null
+++ b/tests/data/metadata/fence_wti.xml
@@ -0,0 +1,148 @@
+<?xml version="1.0" ?>
+<resource-agent name="fence_wti" shortdesc="Fence agent for WTI" >
+<longdesc>fence_wti is an I/O Fencing agent which can be used with the WTI Network Power Switch (NPS). It logs into an NPS via telnet or ssh and boots a specified plug. Lengthy telnet connections to the NPS should be avoided while a GFS cluster is running because the connection will block any necessary fencing actions.</longdesc>
+<vendor-url>http://www.wti.com</vendor-url>
+<parameters>
+	<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="cmd_prompt" unique="0" required="0">
+		<getopt mixed="-c, --command-prompt=[prompt]" />
+		<content type="string" default="['RSM>', 'MPC>', 'IPS>', 'TPS>', 'NBB>', 'NPS>', 'VMR>']"  />
+		<shortdesc lang="en">Force Python regex for command prompt</shortdesc>
+	</parameter>
+	<parameter name="identity_file" unique="0" required="0">
+		<getopt mixed="-k, --identity-file=[filename]" />
+		<content type="string"  />
+		<shortdesc lang="en">Identity file for ssh</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="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</shortdesc>
+	</parameter>
+	<parameter name="ipport" unique="0" required="0">
+		<getopt mixed="-u, --ipport=[port]" />
+		<content type="string" default="23"  />
+		<shortdesc lang="en">TCP/UDP port to use for connection with device</shortdesc>
+	</parameter>
+	<parameter name="login" unique="0" required="0">
+		<getopt mixed="-l, --username=[name]" />
+		<content type="string"  />
+		<shortdesc lang="en">Login Name</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="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="port" unique="0" required="1">
+		<getopt mixed="-n, --plug=[id]" />
+		<content type="string"  />
+		<shortdesc lang="en">Physical plug number, name of virtual machine or UUID</shortdesc>
+	</parameter>
+	<parameter name="secure" unique="0" required="0">
+		<getopt mixed="-x, --ssh" />
+		<content type="boolean"  />
+		<shortdesc lang="en">SSH connection</shortdesc>
+	</parameter>
+	<parameter name="ssh_options" unique="0" required="0">
+		<getopt mixed="--ssh-options=[options]" />
+		<content type="string"  />
+		<shortdesc lang="en">SSH options to use</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="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="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="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="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>
+	<parameter name="ssh_path" unique="0" required="0">
+		<getopt mixed="--ssh-path=[path]" />
+		<content type="string" default="/usr/bin/ssh"  />
+		<shortdesc lang="en">Path to ssh binary</shortdesc>
+	</parameter>
+	<parameter name="telnet_path" unique="0" required="0">
+		<getopt mixed="--telnet-path=[path]" />
+		<content type="string" default="/usr/bin/telnet"  />
+		<shortdesc lang="en">Path to telnet binary</shortdesc>
+	</parameter>
+</parameters>
+<actions>
+	<action name="on" automatic="0"/>
+	<action name="off" />
+	<action name="reboot" />
+	<action name="status" />
+	<action name="list" />
+	<action name="list-status" />
+	<action name="monitor" />
+	<action name="metadata" />
+	<action name="validate-all" />
+</actions>
+</resource-agent>
diff --git a/tests/data/metadata/fence_xenapi.xml b/tests/data/metadata/fence_xenapi.xml
new file mode 100644
index 0000000..fcfaf3a
--- /dev/null
+++ b/tests/data/metadata/fence_xenapi.xml
@@ -0,0 +1,103 @@
+<?xml version="1.0" ?>
+<resource-agent name="fence_xenapi" shortdesc="Fence agent for Citrix XenServer over XenAPI" >
+<longdesc>fence_cxs is an I/O Fencing agent used on Citrix XenServer hosts. It uses the XenAPI, supplied by Citrix, to establish an XML-RPC sesssion to a XenServer host. Once the session is established, further XML-RPC commands are issued in order to switch on, switch off, restart and query the status of virtual machines running on the host.</longdesc>
+<vendor-url>http://www.xenproject.org</vendor-url>
+<parameters>
+	<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="0">
+		<getopt mixed="-l, --username=[name]" />
+		<content type="string"  />
+		<shortdesc lang="en">Login Name</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="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="port" unique="0" required="1">
+		<getopt mixed="-n, --plug=[id]" />
+		<content type="string"  />
+		<shortdesc lang="en">Physical plug number, name of virtual machine or UUID</shortdesc>
+	</parameter>
+	<parameter name="session_url" unique="0" required="1">
+		<getopt mixed="-s, --session-url" />
+		<content type="string"  />
+		<shortdesc lang="en">The URL of the XenServer host.</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="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="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="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="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="list-status" />
+	<action name="monitor" />
+	<action name="metadata" />
+	<action name="validate-all" />
+</actions>
+</resource-agent>
diff --git a/tests/data/metadata/fence_zvmip.xml b/tests/data/metadata/fence_zvmip.xml
new file mode 100644
index 0000000..f698dfe
--- /dev/null
+++ b/tests/data/metadata/fence_zvmip.xml
@@ -0,0 +1,140 @@
+<?xml version="1.0" ?>
+<resource-agent name="fence_zvmip" shortdesc="Fence agent for use with z/VM Virtual Machines" >
+<longdesc>The fence_zvm agent is intended to be used with with z/VM SMAPI service via TCP/IP
+
+To  use this agent the z/VM SMAPI service needs to be configured to allow the virtual machine running this agent to connect to it and issue
+the image_recycle operation.  This involves updating the VSMWORK1 AUTHLIST VMSYS:VSMWORK1. file. The entry should look something similar to
+this:
+
+Column 1                   Column 66                Column 131
+
+   |                          |                        |
+   V                          V                        V
+
+XXXXXXXX                      ALL                      IMAGE_OPERATIONS
+
+Where XXXXXXX is the name of the virtual machine used in the authuser field of the request.
+</longdesc>
+<vendor-url>http://www.ibm.com</vendor-url>
+<parameters>
+	<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="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="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</shortdesc>
+	</parameter>
+	<parameter name="ipport" unique="0" required="0">
+		<getopt mixed="-u, --ipport=[port]" />
+		<content type="string" default="44444"  />
+		<shortdesc lang="en">TCP/UDP port to use for connection with device</shortdesc>
+	</parameter>
+	<parameter name="login" unique="0" required="1">
+		<getopt mixed="-l, --username=[name]" />
+		<content type="string"  />
+		<shortdesc lang="en">Login Name</shortdesc>
+	</parameter>
+	<parameter name="method" unique="0" required="0">
+		<getopt mixed="-m, --method=[method]" />
+		<content type="select" default="onoff"  >
+			<option value="onoff" />
+			<option value="cycle" />
+		</content>
+		<shortdesc lang="en">Method to fence (onoff|cycle)</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="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="port" unique="0" required="1">
+		<getopt mixed="-n, --plug=[id]" />
+		<content type="string"  />
+		<shortdesc lang="en">Physical plug number, name of virtual machine or UUID</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="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="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="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="shell_timeout" unique="0" required="0">
+		<getopt mixed="--shell-timeout=[seconds]" />
+		<content type="string" default="5.0"  />
+		<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="list-status" />
+	<action name="monitor" />
+	<action name="metadata" />
+	<action name="validate-all" />
+</actions>
+</resource-agent>

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/debian-ha/fence-agents.git



More information about the Debian-HA-Commits mailing list