On 12/16/2013 05:14 PM, Marek Grac wrote:
Hi,
Thanks for a patches,
On 12/11/2013 09:46 AM, Bogdan Dobrelya wrote:
Hello.
Description for suggested patches:
fence_virsh: I believe the uuid support is a good idea, cuz every
spawned VM would have an UUID in its dmidecode, equal to its `virsh
domuuid`. Thus, to fence it, we should not either know the domain name,
nor query libvirt to find it out.
Based on your patch, I have sent a new patch to cluster-devel@ ; the
main difference is that patch is based on current version (as there
were several changes vs RHEL6). The other difference is that I have
removed obtaining status of plug from list function because it can not
work easily with UUID. Instead we call directly 'virsh domstate' ; on
older systems there can be a problem with 'virsh --uuid --all' because
'--uuid' is relatively new (yes, supported in RHEL6+) so I did not use
this feature.
fence_apc: As I can see from my research activities, fence_apc is quite
a vendor specific agent, thus it would require custom options for
command-prompt as well as ssh-options.
--ssh-options are already available in upstream
m,
Hello.
Thank you for your support. I'd be glad to see it implemented in upstream.
One more thing.
As far as I was testing my Tripplite PDU device with standard fence
agents, I've tried to find any suitable agent for it (fence_apc,
fence_apc_snmp) but didn't succeed. That's why I've played with
cmd-prompt and ssh-options of fence_apc agent mentioned above.
But I've managed to succeed with customized fence_pdu_snmp (not with
fence_pdu tho) agent I created from fence_apc_snmp with minimal changes
(fixed OIDs and that is almost all).
I'd like to propose this fence_pdu_snmp agent as well (tested with
PDUMH20HVNET 12.04.0055 (snmp v1,v2c,v3) device). See a patch in
attachement, targeted for RHEL6 branch. I believe, it might be
compatible with any switched PDU devices, if slightly modified.
--
Best regards,
Bogdan Dobrelya,
Researcher TechLead, Mirantis, Inc.
+38 (066) 051 07 53
Skype bogdando_at_yahoo.com
Irc #bogdando
38, Lenina ave.
Kharkov, Ukraine
www.mirantis.com
www.mirantis.ru
bdobre...@mirantis.com
>From ce75ca6a7a6a958ff6558be36b91736915ddf881 Mon Sep 17 00:00:00 2001
From: Bogdan Dobrelya <bogda...@mail.ru>
Date: Mon, 16 Dec 2013 18:00:42 +0200
Subject: [PATCH] Add fence_pdu_snmp agent for Tripplite switched PDUs
Signed-off-by: Bogdan Dobrelya <bogda...@mail.ru>
---
fence/agents/pdu_snmp/Makefile.am | 18 ++++
fence/agents/pdu_snmp/README | 13 +++
fence/agents/pdu_snmp/fence_pdu_snmp.py | 176 +++++++++++++++++++++++++++++++
3 files changed, 207 insertions(+)
create mode 100644 fence/agents/pdu_snmp/Makefile.am
create mode 100644 fence/agents/pdu_snmp/README
create mode 100644 fence/agents/pdu_snmp/fence_pdu_snmp.py
diff --git a/fence/agents/pdu_snmp/Makefile.am b/fence/agents/pdu_snmp/Makefile.am
new file mode 100644
index 0000000..835b950
--- /dev/null
+++ b/fence/agents/pdu_snmp/Makefile.am
@@ -0,0 +1,18 @@
+MAINTAINERCLEANFILES = Makefile.in
+
+TARGET = fence_pdu_snmp
+
+SRC = $(TARGET).py
+
+EXTRA_DIST = $(SRC) \
+ README
+
+sbin_SCRIPTS = $(TARGET)
+
+man_MANS = $(TARGET).8
+
+include $(top_srcdir)/make/fencebuild.mk
+include $(top_srcdir)/make/fenceman.mk
+
+clean-local: clean-man
+ rm -f $(TARGET)
diff --git a/fence/agents/pdu_snmp/README b/fence/agents/pdu_snmp/README
new file mode 100644
index 0000000..724962d
--- /dev/null
+++ b/fence/agents/pdu_snmp/README
@@ -0,0 +1,13 @@
+This is an snmp based fence agent for Tripplite switched PDU devices to be used
+with RHEL6 Red Hat Cluster Suite.
+
+In order to use this agent, you will need to have net-snmp-utils installed
+on every node in your cluster. net-snmp-utils is scheduled for inclusion
+in the base RHEL distribution for Update 4, and is yummable in FC5.
+
+To use the agent, cp the agent to the /sbin directory on every
+cluster node. The interface for the fence_pdu_snmp agent is identical to
+the existing fence_apc_snmp agent.
+
+NOTE: The fence_pdu_snmp agent does not support ganged or 'daisy-chained'
+PDU switches.
diff --git a/fence/agents/pdu_snmp/fence_pdu_snmp.py b/fence/agents/pdu_snmp/fence_pdu_snmp.py
new file mode 100644
index 0000000..245f180
--- /dev/null
+++ b/fence/agents/pdu_snmp/fence_pdu_snmp.py
@@ -0,0 +1,176 @@
+#!/usr/bin/python
+
+# The Following agent has been tested on Centos 6.4:
+# PDUMH20HVNET 12.04.0055 snmp v1,v2c,v3
+
+import sys, re, pexpect
+sys.path.append("@FENCEAGENTSLIBDIR@")
+from fencing import *
+from fencing_snmp import *
+
+#BEGIN_VERSION_GENERATION
+RELEASE_VERSION="UNKNOWN"
+BUILD_DATE="(built Tue Dec 10 10:03:37 EST 2013)"
+REDHAT_COPYRIGHT="Copyright (C) Red Hat, Inc. 2004-2010 All rights reserved."
+#END_VERSION_GENERATION
+
+### CONSTANTS ###
+# oid defining fence device
+OID_SYS_OBJECT_ID='.1.3.6.1.2.1.1.2.0'
+
+### GLOBAL VARIABLES ###
+# Device - see PDU
+device=None
+
+# Port ID
+port_id=None
+# Switch ID
+switch_id=None
+
+# Classes describing Device params
+class PDU:
+ # 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'
+ # Names for outlets
+ 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
+
+### FUNCTIONS ###
+def apc_set_device(conn,options):
+ global device
+
+ agents_dir={None:PDU}
+
+ # 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])))):
+ apc_type=[[None,None]]
+
+ device=agents_dir[apc_type[0][1]]
+
+ conn.log_command("Trying %s"%(device.ident_str))
+
+def apc_resolv_port_id(conn,options):
+ global port_id,switch_id,device
+
+ if (device==None):
+ apc_set_device(conn,options)
+
+ # Now we resolv port_id/switch_id
+ if ((options["-n"].isdigit()) and ((not device.has_switches) or (options["-s"].isdigit()))):
+ port_id=int(options["-n"])
+
+ if (device.has_switches):
+ switch_id=int(options["-s"])
+ else:
+ table=conn.walk(device.outlet_table_oid,30)
+
+ for x in table:
+ if (x[1].strip('"')==options["-n"]):
+ t=x[0].split('.')
+ 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):
+ fail_usage("Can't find port with name %s!"%(options["-n"]))
+
+def get_power_status(conn,options):
+ global port_id,switch_id,device
+
+ 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")
+
+def set_power_status(conn, options):
+ global port_id,switch_id,device
+
+ 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["-o"]=="on" and device.turn_on or device.turn_off))
+
+
+def get_outlets_status(conn, options):
+ global device
+
+ result={}
+
+ if (device==None):
+ apc_set_device(conn,options)
+
+ res_ports=conn.walk(device.outlet_table_oid,30)
+
+ for x in res_ports:
+ t=x[0].split('.')
+
+ port_num=((device.has_switches) and "%s:%s"%(t[len(t)-3],t[len(t)-1]) or "%s"%(t[len(t)-1]))
+
+ port_name=x[1].strip('"')
+ port_status=""
+ result[port_num]=(port_name,port_status)
+
+ 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 = [ "help", "version", "agent", "quiet", "verbose", "debug",
+ "action", "ipaddr", "login", "passwd", "passwd_script",
+ "test", "port", "separator", "no_login", "no_password",
+ "snmp_version", "community", "snmp_auth_prot", "snmp_sec_level",
+ "snmp_priv_prot", "snmp_priv_passwd", "snmp_priv_passwd_script",
+ "udpport","inet4_only","inet6_only",
+ "power_timeout", "shell_timeout", "login_timeout", "power_wait" ]
+
+ atexit.register(atexit_handler)
+
+ snmp_define_defaults ()
+ apc_snmp_define_defaults()
+
+ options=check_input(device_opt,process_input(device_opt))
+
+ ## Support for -n [switch]:[plug] notation that was used before
+ if ((options.has_key("-n")) and (-1 != options["-n"].find(":"))):
+ (switch, plug) = options["-n"].split(":", 1)
+ if ((switch.isdigit()) and (plug.isdigit())):
+ options["-s"] = switch
+ options["-n"] = plug
+
+ if (not (options.has_key("-s"))):
+ options["-s"]="1"
+
+ docs = { }
+ docs["shortdesc"] = "Fence agent for Tripplite PDU over SNMP"
+ docs["longdesc"] = "fence_pdu_snmp is an I/O Fencing agent \
+which can be used with the switched Tripplite PDU. It logs \
+into a device via SNMP and controles a specified outlet. It supports \
+SNMP v1, v2c, v3 with all combinations of authenticity/privacy settings.\
+ You should use the MIB file(s) provided with PDU device, if any."
+ docs["vendorurl"] = "http://www.tripplite.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()
--
1.7.10.4