[Cluster-devel] Adding a fence agent
Dwight Hubbard
dwight.hubbard at efausol.com
Fri Jul 3 02:39:07 UTC 2009
Here's what I have so far:
#!/usr/bin/python
#######
# Fencing agent for Digital Loggers Web PowerSwitch II
# Written by Dwight Hubbard dwight.hubbard at efausol.com
# Licensed as GPL Version 2
######
# $Revision: 1.4 $
######
# Information for this device is available at:
# http://www.digital-loggers.com/lpc.html
######
## The Following Agent Has Been Tested On:
##
## Version Firmware
## +-----------------------+--------------------------------------+
## DLI Web PowerSwitch II Version 1.2.C (Apr 12 2009 / 14:28:13)
#####
#
# Note, this specific switch only supports managment via http on
# port 80 so the only option is to use screen scraping. This means
# that firmware updates have a good chance of causing this fence
# script to quit working.
import re,time,sys,pycurl,BeautifulSoup
sys.path.append("/usr/share/fence")
from fencing import *
DEBUG=False
class DLIPower:
def __init__(self,userid='admin',password='4321',hostname='192.168.0.100'):
self.userid=userid
self.password=password
self.hostname=hostname
self.contents=''
def body_callback(self,buf):
self.contents=self.contents+buf
def geturl(self,url='index.htm') :
self.contents=''
curl = pycurl.Curl()
curl.setopt(curl.URL, 'http://%s:%s@%s/%s' %
(self.userid,self.password,self.hostname,url))
curl.setopt(curl.WRITEFUNCTION, self.body_callback)
curl.perform()
curl.close()
return self.contents
def off(self,outlet=0):
# Return Values
# 0 - Sucessfully turned off the outlet
# 1 - Failed to turn off the outlet
self.geturl(url= 'outlet?%d=OFF' % outlet)
time.sleep(1)
if self.status(outlet) == 2:
return 0
else:
print 'bad status returned'
return 1
def on(self,outlet=0):
# Return Values
# 0 - Sucessfully turned on the outlet
# 1 - Failed to turn on the outlet
self.geturl(url= 'outlet?%d=ON' % outlet)
time.sleep(1)
if self.status(outlet) == 0:
return 0
else:
return 1
def reboot(self,outlet=0):
# Return Values
# 0 - Sucessfully turned on the outlet
# 1 - Failed to turn on the outlet
if self.status(outlet) == 0:
rc=self.off(outlet)
else:
rc=0
if rc == 0:
self.on(outlet)
return rc
def statuslist(self):
# Return status informaton in a list format
# each list item consists of a list with 3 items (port #,
name, state)
outlets=[]
soup=BeautifulSoup.BeautifulSoup(self.geturl('index.htm'))
powertable=soup.findAll('table')[5]
for temp in powertable.findAll('tr')[2:]:
columns=temp.findAll('td')
plugnumber=columns[0].string
hostname=columns[1].string
state=columns[2].find('font').string
outlets.append([int(plugnumber),hostname,state])
return outlets
def allstatus(self):
# print all the outlet status
print 'Outlet\t%-15.15s\tState' % 'Hostname'
for item in self.statuslist():
print '%d\t%-15.15s\t%s' % (item[0],item[1],item[2])
def status(self,outlet=0):
# Return Values
# 0 - The port is on
# 1 - We got an unexpected result (possible wrong device??)
# 2 - The port is off
outlets=self.statuslist()
if outlet:
for plug in outlets:
if plug[0] == outlet:
state=plug[2]
if state in ['ON','On', 'on']:
return 0
else:
return 2
return 1
def parsestdin():
options={}
for line in sys.stdin.readlines():
item=line.strip().split('=')
if len(item) > 1:
options[item[0]]=item[1]
return options
if __name__ == "__main__":
# Parse the input and verify we have all required options
options=parsestdin()
if DEBUG:
d=open('/tmp/fence_dli.debug','a')
d.write('BEGIN------------------------------\n')
for item in options.keys():
d.write('%s=%s' % (item,options[item]))
d.write('\n')
if ('port' in options.keys() and 'option' in options.keys()) and
('name' in options.keys() or 'ipaddr' in options.keys()):
# Set the userid/password to the defaults for the switch
# and then allow the options to override them.
password='4321'
userid ='admin'
if 'passwd' in options.keys(): password=options['passwd']
if 'login' in options.keys(): userid =options['login']
if 'name' in options.keys(): host =options['name']
if 'ipaddr' in options.keys(): host =options['ipaddr']
port=int(options['port'])
# Connect to the switch and perform the requested operation
switch=DLIPower(userid=userid,password=password,hostname=host)
if options['option'] == 'off':
sys.exit(switch.off(port))
if options['option'] == 'on':
sys.exit(switch.on(port))
if options['option'] == 'reboot':
rc=switch.reboot(port)
if DEBUG:
d.write('calling reboot, return code %d\n' % rc )
sys.exit(rc)
if options['option'] == 'status':
sys.exit(switch.status(port))
else:
if DEBUG:
d.write('Missing options\n')
d.write('\n')
d.close()
exit(1)
On Wed, Jul 1, 2009 at 9:52 PM, Fabio M. Di Nitto <fdinitto at redhat.com> wrote:
>
> Hi Dwight,
>
> On Wed, 2009-07-01 at 17:20 -0700, Dwight Hubbard wrote:
> > I created a fence agent script for the Digital Loggers WebSwitch II
> > which seems to be working in accordance to the fencing documentation.
> >
> > Now I have a question. How do I install the script to work properly
> > with the cluster management tools?
> >
> > It looks like system-config-cluster is pretty monolithic and I would
> > like to be able to install it in a way that updates, etc don't end up
> > overwriting everything. Not to mention, the manual editing of the
> > cluster.conf is a royal pain.
>
> The best solution would be for you to submit the fence agents to us so
> that it can be included in standard releases and maintained together
> with management tools. This would solve the problem in the long run.
>
> For the short term you can install the agent in the same /sbin
> or /usr/sbin directories as the others (it won't be overwritten), but
> unless you are dealing to patch the management tools, they won't be able
> to know anything about it.
>
> I believe the management tools (conga specifically) are changing to
> automatically import fence agents data and adapt automatically but they
> are not there yet.
>
> Fabio
>
--
Dwight Hubbard
Owner Effective Automation Solutions
Website: http://effectiveautomationsolutions.com
Blog: http://computing.dwighthubbard.info
Email: dwight at dwighthubbard.com
Phone: (503) 616-4493
Redhat Certified Engineer - RHCE #804007137224095
VMware Certified Professional - VCP #18529
More information about the Cluster-devel
mailing list