Page MenuHomeClusterLabs Projects

No OneTemporary

diff --git a/fence/agents/alom/fence_alom.py b/fence/agents/alom/fence_alom.py
index 2a72d7e8..c2af527c 100644
--- a/fence/agents/alom/fence_alom.py
+++ b/fence/agents/alom/fence_alom.py
@@ -1,66 +1,66 @@
-#!/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, time
import atexit
sys.path.append("@FENCEAGENTSLIBDIR@")
from fencing import *
#BEGIN_VERSION_GENERATION
RELEASE_VERSION="Sun Advanced Lights Out Manager (ALOM)"
REDHAT_COPYRIGHT=""
BUILD_DATE=""
#END_VERSION_GENERATION
def get_power_status(conn, options):
conn.send_eol("showplatform")
conn.log_expect(options, options["--command-prompt"], int(options["--shell-timeout"]))
status = re.search("standby", conn.before.lower())
result = (status != None and "off" or "on")
return result
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"]))
# 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" ]
atexit.register(atexit_handler)
all_opt["secure"]["default"] = "1"
all_opt["cmd_prompt"]["default"] = [ r"sc\>\ " ]
options = check_input(device_opt, process_input(device_opt))
options["telnet_over_ssh"] = 1
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
sys.exit(result)
if __name__ == "__main__":
main()
diff --git a/fence/agents/amt/fence_amt.py b/fence/agents/amt/fence_amt.py
index 497976be..b4618312 100644
--- a/fence/agents/amt/fence_amt.py
+++ b/fence/agents/amt/fence_amt.py
@@ -1,156 +1,156 @@
-#!/usr/bin/python
+#!/usr/bin/python -tt
import sys, subprocess, re
import logging
import atexit
from pipes import quote
sys.path.append("@FENCEAGENTSLIBDIR@")
from fencing import *
from fencing import fail_usage, is_executable, SUDO_PATH, LOG_MODE_VERBOSE
#BEGIN_VERSION_GENERATION
RELEASE_VERSION="Fence agent for Intel AMT"
REDHAT_COPYRIGHT=""
BUILD_DATE=""
#END_VERSION_GENERATION
def get_power_status(_, options):
cmd = create_command(options, "status")
try:
logging.debug("Running: %s" % cmd)
process = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
except OSError:
fail_usage("Amttool not found or not accessible")
process.wait()
out = process.communicate()
process.stdout.close()
process.stderr.close()
logging.debug("%s\n" % str(out))
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"
def set_power_status(_, options):
cmd = create_command(options, options["--action"])
try:
logging.debug("Running: %s" % cmd)
process = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
except OSError:
fail_usage("Amttool not found or not accessible")
process.wait()
out = process.communicate()
process.stdout.close()
process.stderr.close()
logging.debug("%s\n" % str(out))
return
def reboot_cycle(_, options):
cmd = create_command(options, "cycle")
try:
logging.debug("Running: %s" % cmd)
process = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
except OSError:
fail_usage("Amttool not found or not accessible")
status = process.wait()
out = process.communicate()
process.stdout.close()
process.stderr.close()
logging.debug("%s\n" % str(out))
return not bool(status)
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
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
}
def main():
atexit.register(atexit_handler)
device_opt = [ "ipaddr", "no_login", "passwd", "boot_option", "no_port",
"sudo", "amttool_path", "method" ]
define_new_opts()
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 \
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)
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)
sys.exit(result)
if __name__ == "__main__":
main()
diff --git a/fence/agents/apc/fence_apc.py b/fence/agents/apc/fence_apc.py
index 3b17cd02..1e86c07f 100644
--- a/fence/agents/apc/fence_apc.py
+++ b/fence/agents/apc/fence_apc.py
@@ -1,271 +1,271 @@
-#!/usr/bin/python
+#!/usr/bin/python -tt
#####
##
## The Following Agent Has Been Tested On:
##
## Model Firmware
## +---------------------------------------------+
## AP7951 AOS v2.7.0, PDU APP v2.7.3
## 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
## cipher (des/blowfish) have to be defined
#####
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"
REDHAT_COPYRIGHT=""
BUILD_DATE="March, 2008"
#END_VERSION_GENERATION
def get_power_status(conn, options):
exp_result = 0
outlets = {}
conn.send_eol("1")
conn.log_expect(options, 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)):
switch = 1
if (None != re.compile('.* MasterSwitch plus 2', re.IGNORECASE | re.S).match(conn.before)):
if (0 == options.has_key("--switch")):
fail_usage("Failed: You have to enter physical switch number")
else:
if (0 == options.has_key("--switch")):
options["--switch"] = "1"
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)):
admin = 0
else:
admin = 1
if switch == 0:
if version == 2:
if admin == 0:
conn.send_eol("2")
else:
conn.send_eol("3")
else:
conn.send_eol("2")
conn.log_expect(options, 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"]))
lines = conn.before.split("\n")
show_re = re.compile(r'(^|\x0D)\s*(\d+)- (.*?)\s+(ON|OFF)\s*')
for x in lines:
res = show_re.search(x)
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"]))
if ["list", "monitor"].count(options["--action"]) == 1:
return outlets
else:
try:
(_, status) = outlets[options["--plug"]]
return status.lower().strip()
except KeyError:
fail(EC_STATUS)
def set_power_status(conn, options):
action = {
'on' : "1",
'off': "2"
}[options["--action"]]
conn.send_eol("1")
conn.log_expect(options, 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)):
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")):
fail_usage("Failed: You have to enter physical switch number")
else:
if (0 == options.has_key("--switch")):
options["--switch"] = 1
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)):
admin2 = 0
else:
admin2 = 1
if switch == 0:
if version == 2:
if admin2 == 0:
conn.send_eol("2")
else:
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)):
admin3 = 0
else:
admin3 = 1
conn.send_eol("1")
else:
conn.send_eol(options["--switch"])
while 0 == conn.log_expect(options,
[ "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"]))
if switch == 0:
if admin2 == 1:
conn.send_eol("1")
conn.log_expect(options, 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"]))
else:
conn.send_eol("1")
conn.log_expect(options, 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.send_eol("YES")
conn.log_expect(options, "Press <ENTER> to continue...", int(options["--shell-timeout"]))
conn.send_eol("")
conn.log_expect(options, options["--command-prompt"], int(options["--shell-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"]))
def get_power_status5(conn, options):
outlets = {}
conn.send_eol("olStatus all")
conn.log_expect(options, options["--command-prompt"], int(options["--shell-timeout"]))
lines = conn.before.split("\n")
show_re = re.compile(r'^\s*(\d+): (.*): (On|Off)\s*$', re.IGNORECASE)
for x in lines:
res = show_re.search(x)
if (res != None):
outlets[res.group(1)] = (res.group(2), res.group(3))
if ["list", "monitor"].count(options["--action"]) == 1:
return outlets
else:
try:
(_, status) = outlets[options["--plug"]]
return status.lower().strip()
except KeyError:
fail(EC_STATUS)
def set_power_status5(conn, options):
action = {
'on' : "olOn",
'off': "olOff"
}[options["--action"]]
conn.send_eol(action + " " + options["--plug"])
conn.log_expect(options, options["--command-prompt"], int(options["--power-timeout"]))
def main():
device_opt = [ "ipaddr", "login", "passwd", "cmd_prompt", "secure", \
"port", "switch" ]
atexit.register(atexit_handler)
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["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 \
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."
docs["vendorurl"] = "http://www.apc.com"
show_docs(options, docs)
## Support for --plug [switch]:[plug] notation that was used before
if (options.has_key("--plug") == 1) and (-1 != options["--plug"].find(":")):
(switch, plug) = options["--plug"].split(":", 1)
options["--switch"] = switch
options["--plug"] = plug
##
## Operate the fencing device
####
conn = fence_login(options)
## Detect firmware version (ASCII menu vs command-line interface)
## and continue with proper action
####
result = -1
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
sys.exit(result)
if __name__ == "__main__":
main()
diff --git a/fence/agents/apc_snmp/fence_apc_snmp.py b/fence/agents/apc_snmp/fence_apc_snmp.py
index b07d04a5..24614762 100644
--- a/fence/agents/apc_snmp/fence_apc_snmp.py
+++ b/fence/agents/apc_snmp/fence_apc_snmp.py
@@ -1,213 +1,213 @@
-#!/usr/bin/python
+#!/usr/bin/python -tt
# The Following agent has been tested on:
# - 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
sys.path.append("@FENCEAGENTSLIBDIR@")
from fencing import *
from fencing_snmp import *
#BEGIN_VERSION_GENERATION
RELEASE_VERSION="APC SNMP fence agent"
REDHAT_COPYRIGHT=""
BUILD_DATE=""
#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 ApcRPDU, ApcMSP, ApcMS, TripplitePDU
device = None
# Port ID
port_id = None
# Switch ID
switch_id = None
# Classes describing Device params
class TripplitePDU:
# 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:
# 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'
outlet_table_oid = '.1.3.6.1.4.1.318.1.1.12.3.5.1.1.2'
ident_str = "APC rPDU"
state_on = 1
state_off = 2
turn_on = 1
turn_off = 2
has_switches = False
class ApcMSP:
# 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'
outlet_table_oid = '.1.3.6.1.4.1.318.1.1.6.7.1.1.4'
ident_str = "APC Master Switch+"
state_on = 1
state_off = 2
turn_on = 1
turn_off = 3
has_switches = True
class ApcMS:
# 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'
outlet_table_oid = '.1.3.6.1.4.1.318.1.1.4.4.2.1.4'
ident_str = "APC Master Switch (fallback)"
state_on = 1
state_off = 2
turn_on = 1
turn_off = 2
has_switches = False
### FUNCTIONS ###
def apc_set_device(conn, options):
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,
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])))):
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
if (device == None):
apc_set_device(conn, options)
# Now we resolv port_id/switch_id
if ((options["--plug"].isdigit()) and ((not device.has_switches) or (options["--switch"].isdigit()))):
port_id = int(options["--plug"])
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"]):
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["--plug"]))
def get_power_status(conn, options):
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):
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))
def get_outlets_status(conn, options):
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 = [ "ipaddr", "login", "passwd", "no_login", "no_password", \
"port", "snmp_version", "community" ]
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("--plug")) and (-1 != options["--plug"].find(":"))):
(switch, plug) = options["--plug"].split(":", 1)
if ((switch.isdigit()) and (plug.isdigit())):
options["--switch"] = switch
options["--plug"] = plug
if (not (options.has_key("--switch"))):
options["--switch"] = "1"
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.\
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."
docs["vendorurl"] = "http://www.apc.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/bladecenter/fence_bladecenter.py b/fence/agents/bladecenter/fence_bladecenter.py
index 3bb02fc3..0f59f558 100644
--- a/fence/agents/bladecenter/fence_bladecenter.py
+++ b/fence/agents/bladecenter/fence_bladecenter.py
@@ -1,120 +1,120 @@
-#!/usr/bin/python
+#!/usr/bin/python -tt
#####
##
## The Following Agent Has Been Tested On:
##
## Model Firmware
## +--------------------+---------------------------+
## (1) Main application BRET85K, rev 16
## Boot ROM BRBR67D, rev 16
## Remote Control BRRG67D, rev 16
##
#####
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"
REDHAT_COPYRIGHT=""
BUILD_DATE="March, 2008"
#END_VERSION_GENERATION
def get_power_status(conn, options):
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"]))
if i == 1:
## Given blade number does not exist
if options.has_key("--missing-as-off"):
return "off"
else:
fail(EC_STATUS)
conn.send_eol("power -state")
conn.log_expect(options, 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"]))
return status.lower().strip()
def set_power_status(conn, options):
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"]))
if i == 1:
## Given blade number does not exist
if options.has_key("--missing-as-off"):
return
else:
fail(EC_GENERIC_ERROR)
conn.send_eol("power -"+options["--action"])
conn.log_expect(options, node_cmd, int(options["--shell-timeout"]))
conn.send_eol("env -T system")
conn.log_expect(options, options["--command-prompt"], int(options["--shell-timeout"]))
def get_blades_list(conn, options):
outlets = { }
node_cmd = "system>"
conn.send_eol("env -T system")
conn.log_expect(options, node_cmd, int(options["--shell-timeout"]))
conn.send_eol("list -l 2")
conn.log_expect(options, node_cmd, int(options["--shell-timeout"]))
lines = conn.before.split("\r\n")
filter_re = re.compile(r"^\s*blade\[(\d+)\]\s+(.*?)\s*$")
for blade_line in lines:
res = filter_re.search(blade_line)
if res != None:
outlets[res.group(1)] = (res.group(2), "")
return outlets
def main():
device_opt = [ "ipaddr", "login", "passwd", "cmd_prompt", "secure", \
"port", "missing_as_off" ]
atexit.register(atexit_handler)
all_opt["power_wait"]["default"] = "10"
all_opt["cmd_prompt"]["default"] = [ "system>" ]
options = check_input(device_opt, process_input(device_opt))
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 \
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: )")
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
sys.exit(result)
if __name__ == "__main__":
main()
diff --git a/fence/agents/brocade/fence_brocade.py b/fence/agents/brocade/fence_brocade.py
index c6b2bfc3..a60355d8 100644
--- a/fence/agents/brocade/fence_brocade.py
+++ b/fence/agents/brocade/fence_brocade.py
@@ -1,88 +1,88 @@
-#!/usr/bin/python
+#!/usr/bin/python -tt
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"
REDHAT_COPYRIGHT=""
BUILD_DATE="March, 20013"
#END_VERSION_GENERATION
def get_power_status(conn, options):
conn.send_eol("portCfgShow " + options["--plug"])
conn.log_expect(options, options["--command-prompt"], int(options["--shell-timeout"]))
show_re = re.compile(r'^\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",
'off': "portCfgPersistentDisable"
}[options["--action"]]
conn.send_eol(action + " " + options["--plug"])
conn.log_expect(options, options["--command-prompt"], int(options["--power-timeout"]))
def main():
device_opt = [ "ipaddr", "login", "passwd", "cmd_prompt", "secure", "port", "fabric_fencing" ]
atexit.register(atexit_handler)
all_opt["cmd_prompt"]["default"] = [ "> " ]
options = check_input(device_opt, process_input(device_opt))
options["eol"] = "\n"
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 \
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 Brocade FC switch. \
When the fenced machine is ready to be brought back into the GFS cluster (after reboot) the port on the Brocade \
FC switch needs to be enabled. This can be done by running fence_brocade and specifying the enable action"
docs["vendorurl"] = "http://www.brocade.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
##
## 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
sys.exit(result)
if __name__ == "__main__":
main()
diff --git a/fence/agents/cisco_mds/fence_cisco_mds.py b/fence/agents/cisco_mds/fence_cisco_mds.py
index dc6c41be..6cc189f1 100644
--- a/fence/agents/cisco_mds/fence_cisco_mds.py
+++ b/fence/agents/cisco_mds/fence_cisco_mds.py
@@ -1,107 +1,107 @@
-#!/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
# with BIOS 1.0.16, kickstart 4.1(1c), system 4.1(1c)
# - Cisco MDS 9124 (1 Slot) Chassis ("1/2/4 Gbps FC/Supervisor-2") Motorola, e500
# 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 import fail_usage
from fencing_snmp import *
#BEGIN_VERSION_GENERATION
RELEASE_VERSION="Cisco MDS 9xxx SNMP fence agent"
REDHAT_COPYRIGHT=""
BUILD_DATE=""
#END_VERSION_GENERATION
### CONSTANTS ###
# Cisco admin status
PORT_ADMIN_STATUS_OID = ".1.3.6.1.2.1.75.1.2.2.1.1"
# IF-MIB trees for alias, status and port
ALIASES_OID = ".1.3.6.1.2.1.31.1.1.1.18"
PORTS_OID = ".1.3.6.1.2.1.2.2.1.2"
### GLOBAL VARIABLES ###
# OID converted from fc port name (fc(x)/(y))
PORT_OID = ""
### FUNCTIONS ###
# Convert cisco port name (fc(x)/(y)) to OID
def cisco_port2oid(port):
port = port.lower()
nums = re.match(r'^fc(\d+)/(\d+)$', port)
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):
(_, 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))
def get_outlets_status(conn, options):
result = {}
res_fc = conn.walk(PORTS_OID, 30)
res_aliases = array_to_dict(conn.walk(ALIASES_OID, 30))
fc_re = re.compile(r'^"fc\d+/\d+"$')
for x in res_fc:
if fc_re.match(x[1]):
port_num = 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_status = ""
result[port_name] = (port_alias, port_status)
return result
# Main agent method
def main():
global PORT_OID
device_opt = [ "fabric_fencing", "ipaddr", "login", "passwd", "no_login", "no_password", \
"port", "snmp_version", "community" ]
atexit.register(atexit_handler)
snmp_define_defaults ()
options = check_input(device_opt, process_input(device_opt))
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"])):
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__":
main()
diff --git a/fence/agents/cisco_ucs/fence_cisco_ucs.py b/fence/agents/cisco_ucs/fence_cisco_ucs.py
index 98525152..d2777def 100644
--- a/fence/agents/cisco_ucs/fence_cisco_ucs.py
+++ b/fence/agents/cisco_ucs/fence_cisco_ucs.py
@@ -1,160 +1,160 @@
-#!/usr/bin/python
+#!/usr/bin/python -tt
import sys, re
import pycurl, StringIO
import logging
import time
import atexit
sys.path.append("@FENCEAGENTSLIBDIR@")
from fencing import *
from fencing import fail, EC_STATUS, EC_LOGIN_DENIED, LOG_MODE_VERBOSE
#BEGIN_VERSION_GENERATION
RELEASE_VERSION="New Cisco UCS Agent - test release on steroids"
REDHAT_COPYRIGHT=""
BUILD_DATE="March, 2008"
#END_VERSION_GENERATION
RE_COOKIE = re.compile("<aaaLogin .* outCookie=\"(.*?)\"", re.IGNORECASE)
RE_STATUS = re.compile("<lsPower .*? state=\"(.*?)\"", re.IGNORECASE)
RE_GET_DN = re.compile(" dn=\"(.*?)\"", re.IGNORECASE)
RE_GET_DESC = re.compile(" descr=\"(.*?)\"", re.IGNORECASE)
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"]))
result = RE_STATUS.search(res)
if (result == None):
fail(EC_STATUS)
else:
status = result.group(1)
if (status == "up"):
return "on"
else:
return "off"
def set_power_status(conn, options):
action = {
'on' : "up",
'off' : "down"
}[options["--action"]]
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 = { }
try:
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)
desc = RE_GET_DESC.search(lines[i]).group(1)
outlets[dn] = (desc, None)
except AttributeError:
return { }
except IndexError:
return { }
return outlets
def send_command(opt, command, timeout):
## setup correct URL
if opt.has_key("--ssl"):
url = "https:"
else:
url = "http:"
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()
logging.debug("%s\n" % command)
logging.debug("%s\n" % results)
return result
def define_new_opts():
all_opt["suborg"] = {
"getopt" : "s:",
"longopt" : "suborg",
"help" : "--suborg=[path] Additional path needed to access suborganization",
"required" : "0",
"shortdesc" : "Additional path needed to access suborganization",
"default" : "",
"order" : 1 }
def main():
device_opt = [ "ipaddr", "login", "passwd", "ssl", "notls", "port", "web", "suborg" ]
atexit.register(atexit_handler)
define_new_opts()
options = 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"]))
### Login
try:
res = send_command(options, "<aaaLogin inName=\"" + options["--username"] +
"\" inPassword=\"" + options["--password"] + "\" />", int(options["--login-timeout"]))
result = RE_COOKIE.search(res)
if (result == None):
## Cookie is absenting in response
fail(EC_LOGIN_DENIED)
except:
fail(EC_LOGIN_DENIED)
options["cookie"] = result.group(1)
##
## Modify suborg to format /suborg
if options["--suborg"] != "":
options["--suborg"] = "/" + options["--suborg"].lstrip("/").rstrip("/")
##
## Fence operations
####
result = fence_action(None, options, 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"]))
sys.exit(result)
if __name__ == "__main__":
main()
diff --git a/fence/agents/drac/fence_drac.py b/fence/agents/drac/fence_drac.py
index 396f09e2..b858d625 100644
--- a/fence/agents/drac/fence_drac.py
+++ b/fence/agents/drac/fence_drac.py
@@ -1,81 +1,81 @@
-#!/usr/bin/python
+#!/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("getmodinfo")
conn.log_expect(options, 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 = {
'on' : "powerup",
'off': "powerdown"
}[options["--action"]]
conn.send_eol("serveraction -d 0 " + action)
conn.log_expect(options, options["--command-prompt"], int(options["--shell-timeout"]))
def main():
device_opt = [ "ipaddr", "login", "passwd", "cmd_prompt" ]
atexit.register(atexit_handler)
opt = process_input(device_opt)
if "--username" in opt:
all_opt["cmd_prompt"]["default"] = [ "\\[" + opt["--username"] + "\\]# " ]
else:
all_opt["cmd_prompt"]["default"] = [ "\\[" "username" + "\\]# " ]
options = check_input(device_opt, opt)
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 \
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]# racadm racreset \
"
docs["vendorurl"] = "http://www.dell.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
##
## 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
sys.exit(result)
if __name__ == "__main__":
main()
diff --git a/fence/agents/drac5/fence_drac5.py b/fence/agents/drac5/fence_drac5.py
index cdf4f4f0..7d8fe9aa 100644
--- a/fence/agents/drac5/fence_drac5.py
+++ b/fence/agents/drac5/fence_drac5.py
@@ -1,163 +1,163 @@
-#!/usr/bin/python
+#!/usr/bin/python -tt
#####
##
## The Following Agent Has Been Tested On:
##
## DRAC Version Firmware
## +-----------------+---------------------------+
## DRAC 5 1.0 (Build 06.05.12)
## DRAC 5 1.21 (Build 07.05.04)
##
## @note: drac_version was removed
#####
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"
REDHAT_COPYRIGHT=""
BUILD_DATE="March, 2008"
#END_VERSION_GENERATION
def get_power_status(conn, options):
if options["--drac-version"] == "DRAC MC":
(_, 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(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"
else:
return "off"
def set_power_status(conn, options):
action = {
'on' : "powerup",
'off': "powerdown"
}[options["--action"]]
if options["--drac-version"] == "DRAC CMC":
conn.send_eol("racadm serveraction " + action + " -m " + options["--plug"])
elif options["--drac-version"] == "DRAC 5":
conn.send_eol("racadm serveraction " + action)
elif options["--drac-version"] == "DRAC MC":
conn.send_eol("racadm serveraction -s " + options["--plug"] + " " + action)
## 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"]))
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"]))
def get_list_devices(conn, options):
outlets = { }
if options["--drac-version"] == "DRAC CMC":
conn.send_eol("getmodinfo")
list_re = re.compile(r"^([^\s]*?)\s+Present\s*(ON|OFF)\s*.*$")
conn.log_expect(options, options["--command-prompt"], int(options["--power-timeout"]))
for line in conn.before.splitlines():
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(r"^\s*([^\s]*)\s*---->\s*(.*?)\s+Present\s*(ON|OFF)\s*.*$")
conn.log_expect(options, options["--command-prompt"], int(options["--power-timeout"]))
for line in conn.before.splitlines():
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
## standard fence library can't handle correctly situation
## when some fence devices supported by fence agent
## works with 'list' and other should returns 'N/A'
print "N/A"
return outlets
def define_new_opts():
all_opt["drac_version"] = {
"getopt" : "d:",
"longopt" : "drac-version",
"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 }
def main():
device_opt = [ "ipaddr", "login", "passwd", "cmd_prompt", "secure", \
"drac_version", "port", "no_port" ]
atexit.register(atexit_handler)
define_new_opts()
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["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."
docs["vendorurl"] = "http://www.dell.com"
show_docs(options, docs)
##
## Operate the fencing device
######
conn = fence_login(options)
if options.has_key("--drac-version") == False:
## autodetect from text issued by fence device
if conn.before.find("CMC") >= 0:
options["--drac-version"] = "DRAC CMC"
elif conn.before.find("DRAC 5") >= 0:
options["--drac-version"] = "DRAC 5"
elif conn.after.find("DRAC/MC") >= 0:
options["--drac-version"] = "DRAC MC"
else:
## Assume this is DRAC 5 by default as we don't want to break anything
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()):
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
sys.exit(result)
if __name__ == "__main__":
main()
diff --git a/fence/agents/dummy/fence_dummy.py b/fence/agents/dummy/fence_dummy.py
index 8996c74c..ff67e7b1 100644
--- a/fence/agents/dummy/fence_dummy.py
+++ b/fence/agents/dummy/fence_dummy.py
@@ -1,135 +1,135 @@
-#!/usr/bin/python
+#!/usr/bin/python -tt
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"
REDHAT_COPYRIGHT=""
BUILD_DATE=""
#END_VERSION_GENERATION
plug_status = "on"
def get_power_status_file(conn, options):
try:
status_file = open(options["--status-file"], 'r')
except:
return "off"
status = status_file.read()
status_file.close()
return status.lower()
def set_power_status_file(conn, options):
if not (options["--action"] in [ "on", "off" ]):
return
status_file = open(options["--status-file"], 'w')
status_file.write(options["--action"])
status_file.close()
def get_power_status_fail(conn, options):
outlets = get_outlets_fail(conn, options)
if len(outlets) == 0 or options.has_key("--plug") == 0:
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
plug_status = "unknown"
if options["--action"] == "on":
plug_status = "off"
def get_outlets_fail(conn, options):
result = {}
global plug_status
if options["--action"] == "on":
plug_status = "off"
# 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":
result["fake_port_1"] = [plug_status, "fake"]
result["fake_port_2"] = [plug_status, "fake"]
elif (options.has_key("--plug") == 0):
fail_usage("Failed: You have to enter existing machine!")
else:
port = options["--plug"]
result[port] = [plug_status, "fake"]
return result
def main():
device_opt = [ "no_password", "status_file", "random_sleep_range", "type", "port" ]
atexit.register(atexit_handler)
all_opt["status_file"] = {
"getopt" : "s:",
"longopt" : "status-file",
"help":"--status-file=[file] Name of file that holds current status",
"required" : "0",
"shortdesc" : "File with status",
"default" : "/tmp/fence_dummy.status",
"order": 1
}
all_opt["random_sleep_range"] = {
"getopt" : "r:",
"longopt" : "random_sleep_range",
"help":"--random_sleep_range=[seconds] Issue a sleep between 1 and [seconds]",
"required" : "0",
"shortdesc" : "Issue a sleep between 1 and X seconds. Used for testing.",
"order": 1
}
all_opt["type"] = {
"getopt" : "t:",
"longopt" : "type",
"help":"--type=[type] Possible types are: file and fail",
"required" : "0",
"shortdesc" : "Type of the dummy fence agent",
"default" : "file",
"order": 1
}
pinput = process_input(device_opt)
if (pinput.has_key("--type") and pinput["--type"] == "file") or (pinput.has_key("--type") == False):
# hack to have fence agents that require ports 'fail' and one that do not 'file'
device_opt.remove("port")
options = check_input(device_opt, process_input(device_opt))
docs = { }
docs["shortdesc"] = "Dummy fence agent"
docs["longdesc"] = "fence_dummy"
docs["vendorurl"] = "http://www.example.com"
show_docs(options, docs)
# random sleep for testing
if options.has_key("--random_sleep_range"):
val = int(options["--random_sleep_range"])
ran = random.randint(1, val)
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__":
main()
diff --git a/fence/agents/eaton_snmp/fence_eaton_snmp.py b/fence/agents/eaton_snmp/fence_eaton_snmp.py
index a329aeb0..f519be85 100644
--- a/fence/agents/eaton_snmp/fence_eaton_snmp.py
+++ b/fence/agents/eaton_snmp/fence_eaton_snmp.py
@@ -1,235 +1,235 @@
-#!/usr/bin/python
+#!/usr/bin/python -tt
# The Following agent has been tested on:
# - Eaton ePDU Managed - SNMP v1
# EATON | Powerware ePDU model: Managed ePDU (PW104MA0UB99), firmware: 01.01.01
# - Eaton ePDU Switched - SNMP v1
# EATON | Powerware ePDU model: Switched ePDU (IPV3600), firmware: 2.0.K
import sys
import atexit
sys.path.append("@FENCEAGENTSLIBDIR@")
from fencing import *
from fencing_snmp import *
#BEGIN_VERSION_GENERATION
RELEASE_VERSION="Eaton SNMP fence agent"
REDHAT_COPYRIGHT=""
BUILD_DATE=""
#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 EatonManagedePDU, EatonSwitchedePDU
device = None
# Port ID
port_id = None
# Switch ID
switch_id = None
# Did we issue a set before get (to adjust OID with Switched ePDU)
after_set = False
# Classes describing Device params
# Managed ePDU
class EatonManagedePDU:
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'
ident_str = "Eaton Managed ePDU"
state_off = 0
state_on = 1
state_cycling = 2 # FIXME: not usable with fence-agents
turn_off = 0
turn_on = 1
turn_cycle = 2 # FIXME: not usable with fence-agents
has_switches = False
# Switched ePDU (Pulizzi 2)
# NOTE: sysOID reports "20677.1", while data are actually at "20677.2"
class EatonSwitchedePDU:
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'
ident_str = "Eaton Switched ePDU"
state_off = 2
state_on = 1
state_cycling = 0 # Note: this status doesn't exist on this device
turn_off = 2
turn_on = 1
turn_cycle = 3 # FIXME: not usable with fence-agents
has_switches = False
### FUNCTIONS ###
def eaton_set_device(conn, options):
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 }
# 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])))):
eaton_type = [[None, None]]
device = agents_dir[eaton_type[0][1]]
conn.log_command("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)
# Restore the increment, that was removed in main for ePDU Managed
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()))):
port_id = int(options["--plug"])
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"]):
t = x[0].split('.')
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"):
port_id = int(t[len(t)-3])
else:
port_id = int(t[len(t)-1])
if (port_id==None):
# Restore index offset, to provide a valid error output on Managed 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):
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")):
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)):
return "on"
elif (status==str(device.state_off)):
return "off"
else:
return None
except:
return None
def set_power_status(conn, options):
global port_id, after_set
after_set = True
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"):
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))
def get_outlets_status(conn, options):
outletCount = 0
result = {}
if (device==None):
eaton_set_device(conn, options)
res_ports = conn.walk(device.outlet_table_oid, 30)
for x in res_ports:
outletCount += 1
status = x[1]
t = x[0].split('.')
# 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)
# Plug indexing start from zero, so we add '1'
# for the user's exposed plug number
port_name = str(int(x[1].strip('"')) + 1)
port_status = ""
result[port_num] = (port_name, port_status)
else:
# Switched ePDU do not propose an outletCount OID!
# Invalid status (ie value == '0'), retrieved via the walk,
# means the outlet is absent
port_num = str(outletCount)
port_name = str(outletCount)
port_status = ""
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" ]
atexit.register(atexit_handler)
snmp_define_defaults ()
all_opt["switch"]["default"] = 1
all_opt["power_wait"]["default"] = 2
all_opt["snmp_version"]["default"] = "1"
all_opt["community"]["default"] = "private"
options = check_input(device_opt, process_input(device_opt))
# 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())):
options["--plug"] = str(int(options["--plug"]) - 1)
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 \
into a device via SNMP and reboots a specified outlet. It supports \
SNMP v1 and v3 with all combinations of authenticity/privacy settings."
docs["vendorurl"] = "http://powerquality.eaton.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/fence_eps.py b/fence/agents/eps/fence_eps.py
index dbf5e5b7..0d9e573f 100644
--- a/fence/agents/eps/fence_eps.py
+++ b/fence/agents/eps/fence_eps.py
@@ -1,126 +1,126 @@
-#!/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, LOG_MODE_VERBOSE
#BEGIN_VERSION_GENERATION
RELEASE_VERSION="ePowerSwitch 8M+ (eps)"
REDHAT_COPYRIGHT=""
BUILD_DATE=""
#END_VERSION_GENERATION
# Run command on EPS device.
# @param options Device options
# @param params HTTP GET parameters (without ?)
def eps_run_command(options, params):
try:
# New http connection
conn = httplib.HTTPConnection(options["--ip"])
request_str = "/"+options["--page"]
if (params!=""):
request_str += "?"+params
logging.debug("GET %s\n" % request_str)
conn.putrequest('GET', request_str)
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"]))
logging.debug("Authorization: %s\n" % auth_str)
conn.putheader('Authorization', auth_str)
conn.endheaders()
response = conn.getresponse()
logging.debug("%d %s\n"%(response.status, response.reason))
#Response != OK -> couldn't login
if (response.status!=200):
fail(EC_LOGIN_DENIED)
result = response.read()
logging.debug("%s \n" % result)
conn.close()
except socket.timeout:
fail(EC_TIMED_OUT)
except socket.error:
fail(EC_LOGIN_DENIED)
return result
def get_power_status(conn, options):
ret_val = eps_run_command(options,"")
result = {}
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"))
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]
else:
return result
def set_power_status(conn, options):
eps_run_command(options, "P%s=%s"%(options["--plug"], (options["--action"]=="on" and "1" or "0")))
# Define new option
def eps_define_new_opts():
all_opt["hidden_page"] = {
"getopt" : "c:",
"longopt" : "page",
"help":"-c, --page=[page] Name of hidden page (default hidden.htm)",
"required" : "0",
"shortdesc" : "Name of hidden page",
"default" : "hidden.htm",
"order": 1
}
# Starting point of fence agent
def main():
device_opt = [ "ipaddr", "login", "passwd", "no_login", "no_password", \
"port", "hidden_page" ]
atexit.register(atexit_handler)
eps_define_new_opts()
options = check_input(device_opt, process_input(device_opt))
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 \
this is only one, which has support for hidden page feature. \
\n.TP\n\
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."
docs["vendorurl"] = "http://www.epowerswitch.com"
show_docs(options, docs)
#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)
sys.exit(result)
if __name__ == "__main__":
main()
diff --git a/fence/agents/hds_cb/fence_hds_cb.py b/fence/agents/hds_cb/fence_hds_cb.py
index 70ca185e..f895fd39 100755
--- a/fence/agents/hds_cb/fence_hds_cb.py
+++ b/fence/agents/hds_cb/fence_hds_cb.py
@@ -1,146 +1,146 @@
-#!/usr/bin/python
+#!/usr/bin/python -tt
#####
##
## The Following Agent Has Been Tested On:
##
## Model Modle/Firmware
## +--------------------+---------------------------+
## (1) Main application CB2000/A0300-E-6617
##
#####
import sys, re
import atexit
sys.path.append("@FENCEAGENTSLIBDIR@")
from fencing import *
#BEGIN_VERSION_GENERATION
RELEASE_VERSION="New Compute Blade 2000 Agent - test release on steroids"
REDHAT_COPYRIGHT=""
BUILD_DATE="November, 2012"
#END_VERSION_GENERATION
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.sendline("PC") # Enter partition control
conn.log_expect(options, 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:
# "P Power Condition LID lamp Mode Auto power on"
# "0 On Normal Off Basic Synchronized"
# "1 On Normal Off Basic Synchronized"
for line in conn.before.splitlines():
# populate the relevant fields based on regex
partition = re.search(RE_STATUS_LINE, line)
if( partition != None):
# find the blade number defined in args
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
# executed. We could in theory save some time by staying in
# 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.sendline("EX") # Back to system console main menu
conn.log_expect(options, options["--command-prompt"], int(options["--shell-timeout"]))
return result
def set_power_status(conn, options):
action = {
'on' : "P",
'off': "F",
'reboot' : "H",
}[options["--action"]]
conn.sendline("S") # Enter System Command Mode
conn.log_expect(options, "SVP>", int(options["--shell-timeout"]))
conn.sendline("PC") # Enter partition control
conn.log_expect(options, 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.sendline(action) # Execute action from array above
conn.log_expect(options, 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.sendline("Y") # Confirm action
conn.log_expect(options, "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.sendline("Q") # Quit back to partition control
conn.log_expect(options, 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.sendline("EX") # Quit back to system console menu
conn.log_expect(options, options["--command-prompt"], int(options["--shell-timeout"]))
def get_blades_list(conn, options):
outlets = { }
conn.sendline("S") # Enter System Command Mode
conn.log_expect(options, "SVP>", int(options["--shell-timeout"]))
conn.sendline("PC") # Enter partition control
conn.log_expect(options, 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"
# "0 On Normal Off Basic Synchronized"
# "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), "")
conn.sendline("Q") # Quit back to system command mode
conn.log_expect(options, "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"]))
return outlets
def main():
device_opt = [ "ipaddr", "login", "passwd", "cmd_prompt", "secure", \
"port", "missing_as_off" ]
atexit.register(atexit_handler)
all_opt["power_wait"]["default"] = "5"
all_opt["cmd_prompt"]["default"] = [ r"\) :" ]
options = check_input(device_opt, process_input(device_opt))
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
sys.exit(result)
if __name__ == "__main__":
main()
diff --git a/fence/agents/hpblade/fence_hpblade.py b/fence/agents/hpblade/fence_hpblade.py
index 6b883db0..636c77d3 100644
--- a/fence/agents/hpblade/fence_hpblade.py
+++ b/fence/agents/hpblade/fence_hpblade.py
@@ -1,97 +1,97 @@
-#!/usr/bin/python
+#!/usr/bin/python -tt
#####
##
## The Following Agent Has Been Tested On:
## * BladeSystem c7000 Enclosure
#####
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"
REDHAT_COPYRIGHT=""
BUILD_DATE="March, 2008"
#END_VERSION_GENERATION
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(r"^\s*Power: (.*?)\s*$")
status = "unknown"
for line in conn.before.splitlines():
res = power_re.search(line)
if res != None:
status = res.group(1)
if status == "unknown":
if options.has_key("--missing-as-off"):
return "off"
else:
fail(EC_STATUS)
return status.lower().strip()
def set_power_status(conn, options):
if options["--action"] == "on":
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"]))
def get_blades_list(conn, options):
outlets = { }
conn.send_eol("show server list" )
conn.log_expect(options, options["--command-prompt"], int(options["--shell-timeout"]))
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:
outlets[res.group(1)] = (res.group(2), res.group(4).lower())
return outlets
def main():
device_opt = [ "ipaddr", "login", "passwd", "cmd_prompt", "secure", "port", "missing_as_off" ]
atexit.register(atexit_handler)
all_opt["cmd_prompt"]["default"] = [ "c7000oa>" ]
options = check_input(device_opt, process_input(device_opt))
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
sys.exit(result)
if __name__ == "__main__":
main()
diff --git a/fence/agents/ibmblade/fence_ibmblade.py b/fence/agents/ibmblade/fence_ibmblade.py
index 1e60e7d9..43bc73e1 100644
--- a/fence/agents/ibmblade/fence_ibmblade.py
+++ b/fence/agents/ibmblade/fence_ibmblade.py
@@ -1,79 +1,79 @@
-#!/usr/bin/python
+#!/usr/bin/python -tt
import sys
import atexit
sys.path.append("@FENCEAGENTSLIBDIR@")
from fencing import *
from fencing_snmp import *
#BEGIN_VERSION_GENERATION
RELEASE_VERSION="IBM Blade SNMP fence agent"
REDHAT_COPYRIGHT=""
BUILD_DATE=""
#END_VERSION_GENERATION
### 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
# Status constants returned as value from SNMP
STATUS_DOWN = 0
STATUS_UP = 1
# Status constants to set as value to SNMP
STATUS_SET_OFF = 0
STATUS_SET_ON = 1
### FUNCTIONS ###
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_blades = conn.walk(STATUSES_OID, 30)
for blade_info in res_blades:
port_num = blade_info[0].split('.')[-1]
port_alias = ""
port_status = (blade_info[1]==str(STATUS_UP) and "on" or "off")
result[port_num] = (port_alias, port_status)
return result
# Main agent method
def main():
device_opt = [ "ipaddr", "login", "passwd", "no_login", "no_password", \
"port", "snmp_version", "community" ]
atexit.register(atexit_handler)
snmp_define_defaults()
all_opt["snmp_version"]["default"] = "1"
options = check_input(device_opt, process_input(device_opt))
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 \
request to BladeCenter chassis, rebooting, powering up or down \
the specified Blade Server."
docs["vendorurl"] = "http://www.ibm.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/ifmib/fence_ifmib.py b/fence/agents/ifmib/fence_ifmib.py
index 3ecc85d3..350ce718 100644
--- a/fence/agents/ifmib/fence_ifmib.py
+++ b/fence/agents/ifmib/fence_ifmib.py
@@ -1,128 +1,128 @@
-#!/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
# with BIOS 1.0.16, kickstart 4.1(1c), system 4.1(1c)
# - Cisco MDS 9124 (1 Slot) Chassis ("1/2/4 Gbps FC/Supervisor-2") Motorola, e500
# with BIOS 1.0.16, kickstart 4.1(1c), system 4.1(1c)
# - Partially with APC PDU (Network Management Card AOS v2.7.0, Rack PDU APP v2.7.3)
# Only lance if is visible
import sys
import atexit
sys.path.append("@FENCEAGENTSLIBDIR@")
from fencing import *
from fencing import fail_usage
from fencing_snmp import *
#BEGIN_VERSION_GENERATION
RELEASE_VERSION="IF:MIB SNMP fence agent"
REDHAT_COPYRIGHT=""
BUILD_DATE=""
#END_VERSION_GENERATION
### CONSTANTS ###
# IF-MIB trees for alias, status and port
ALIASES_OID = ".1.3.6.1.2.1.31.1.1.1.18"
PORTS_OID = ".1.3.6.1.2.1.2.2.1.2"
STATUSES_OID = ".1.3.6.1.2.1.2.2.1.7"
# Status constants returned as value from SNMP
STATUS_UP = 1
STATUS_DOWN = 2
STATUS_TESTING = 3
### GLOBAL VARIABLES ###
# Port number converted from port name or index
port_num = None
### FUNCTIONS ###
# Convert port index or name to port index
def port2index(conn, port):
res = None
if (port.isdigit()):
res = int(port)
else:
ports = conn.walk(PORTS_OID, 30)
for x in ports:
if (x[1].strip('"')==port):
res = int(x[0].split('.')[-1])
break
if (res==None):
fail_usage("Can't find port with name %s!"%(port))
return res
def get_power_status(conn, options):
global port_num
if (port_num==None):
port_num = port2index(conn, options["--plug"])
(_, 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):
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))
def get_outlets_status(conn, options):
result = {}
res_fc = conn.walk(PORTS_OID, 30)
res_aliases = array_to_dict(conn.walk(ALIASES_OID, 30))
for x in res_fc:
port_number = x[0].split('.')[-1]
port_name = x[1].strip('"')
port_alias = (res_aliases.has_key(port_number) and res_aliases[port_number].strip('"') or "")
port_status = ""
result[port_name] = (port_alias, port_status)
return result
# Main agent method
def main():
device_opt = [ "fabric_fencing", "ipaddr", "login", "passwd", "no_login", "no_password", \
"port", "snmp_version", "community" ]
atexit.register(atexit_handler)
snmp_define_defaults ()
all_opt["snmp_version"]["default"] = "2c"
options = check_input(device_opt, process_input(device_opt))
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. \
\n.P\n\
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."
docs["vendorurl"] = "http://www.ietf.org/wg/concluded/ifmib.html"
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/ilo/fence_ilo.py b/fence/agents/ilo/fence_ilo.py
index 87195730..f45e7494 100644
--- a/fence/agents/ilo/fence_ilo.py
+++ b/fence/agents/ilo/fence_ilo.py
@@ -1,132 +1,132 @@
-#!/usr/bin/python
+#!/usr/bin/python -tt
#####
##
## The Following Agent Has Been Tested On:
##
## iLO Version
## +---------------------------------------------+
## iLO / firmware 1.91 / 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"
REDHAT_COPYRIGHT=""
BUILD_DATE="March, 2008"
#END_VERSION_GENERATION
def get_power_status(conn, options):
conn.send("<LOGIN USER_LOGIN = " + quoteattr(options["--username"]) + \
" 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"]))
status = conn.match.group(1)
return status.lower().strip()
def set_power_status(conn, options):
conn.send("<LOGIN USER_LOGIN = " + quoteattr(options["--username"]) + \
" 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["fw_version"] > 1.29:
conn.send("<HOLD_PWR_BTN TOGGLE=\"yes\" />\r\n")
else:
conn.send("<HOLD_PWR_BTN />\r\n")
elif options["--ribcl-version"] < 2.21:
conn.send("<SET_HOST_POWER HOST_POWER = \"" + options["--action"] + "\" />\r\n")
else:
if options["--action"] == "off":
conn.send("<HOLD_PWR_BTN/>\r\n")
else:
conn.send("<PRESS_PWR_BTN/>\r\n")
conn.send("</SERVER_INFO></LOGIN>\r\n")
return
def define_new_opts():
all_opt["ribcl"] = {
"getopt" : "r:",
"longopt" : "ribcl-version",
"help" : "-r, --ribcl-version=[version] Force ribcl version to use",
"required" : "0",
"shortdesc" : "Force ribcl version to use",
"order" : 1 }
def main():
device_opt = [ "ipaddr", "login", "passwd", "ssl", "notls", "ribcl" ]
atexit.register(atexit_handler)
define_new_opts()
all_opt["login_timeout"]["default"] = "10"
all_opt["retry_on"]["default"] = "3"
all_opt["ssl"]["default"] = "1"
options = check_input(device_opt, process_input(device_opt))
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.\
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."
docs["vendorurl"] = "http://www.hp.com"
docs["symlink"] = [("fence_ilo2", "Fence agent for HP iLO2")]
show_docs(options, docs)
##
## Login and get version number
####
conn = fence_login(options)
try:
conn.send("<?xml version=\"1.0\"?>\r\n")
conn.log_expect(options, [ "</RIBCL>", "<END_RIBCL/>" ], int(options["--login-timeout"]))
version = re.compile("<RIBCL VERSION=\"(.*?)\"", re.IGNORECASE).search(conn.before).group(1)
if options.has_key("--ribcl-version") == 0:
options["--ribcl-version"] = float(version)
if options["--ribcl-version"] >= 2:
conn.send("<RIBCL VERSION=\"2.0\">\r\n")
else:
conn.send("<RIBCL VERSION=\"1.2\">\r\n")
conn.send("<LOGIN USER_LOGIN = " + quoteattr(options["--username"]) + \
" PASSWORD = " + quoteattr(options["--password"]) + ">\r\n")
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, r"<GET_FW_VERSION\s*\n", int(options["--shell-timeout"]))
conn.log_expect(options, "/>", 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)
except pexpect.EOF:
fail(EC_LOGIN_DENIED)
##
## Fence operations
####
result = fence_action(conn, options, set_power_status, get_power_status, None)
sys.exit(result)
if __name__ == "__main__":
main()
diff --git a/fence/agents/ilo_mp/fence_ilo_mp.py b/fence/agents/ilo_mp/fence_ilo_mp.py
index c76c281b..1d874c12 100644
--- a/fence/agents/ilo_mp/fence_ilo_mp.py
+++ b/fence/agents/ilo_mp/fence_ilo_mp.py
@@ -1,69 +1,69 @@
-#!/usr/bin/python
+#!/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(options, 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("stop -f /system1")
conn.log_expect(options, options["--command-prompt"], int(options["--power-timeout"]))
return
def main():
device_opt = [ "ipaddr", "login", "passwd", "secure", "cmd_prompt" ]
atexit.register(atexit_handler)
all_opt["cmd_prompt"]["default"] = [ "MP>", "hpiLO->" ]
all_opt["power_wait"]["default"] = 5
options = check_input(device_opt, process_input(device_opt))
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")
##
## Fence operations
####
result = fence_action(conn, options, set_power_status, get_power_status)
try:
conn.send_eol("exit")
except:
pass
sys.exit(result)
if __name__ == "__main__":
main()
diff --git a/fence/agents/intelmodular/fence_intelmodular.py b/fence/agents/intelmodular/fence_intelmodular.py
index bd1faee4..320b2db2 100644
--- a/fence/agents/intelmodular/fence_intelmodular.py
+++ b/fence/agents/intelmodular/fence_intelmodular.py
@@ -1,94 +1,94 @@
-#!/usr/bin/python
+#!/usr/bin/python -tt
# Tested with an Intel MFSYS25 using firmware package 2.6 Should work with an
# MFSYS35 as well.
#
# Notes:
#
# The manual and firmware release notes says SNMP is read only. This is not
# true, as per the MIBs that ship with the firmware you can write to
# the bladePowerLed oid to control the servers.
#
# Thanks Matthew Kent for original agent and testing.
import sys
import atexit
sys.path.append("@FENCEAGENTSLIBDIR@")
from fencing import *
from fencing_snmp import *
#BEGIN_VERSION_GENERATION
RELEASE_VERSION="Intel Modular SNMP fence agent"
REDHAT_COPYRIGHT=""
BUILD_DATE=""
#END_VERSION_GENERATION
### CONSTANTS ###
# From INTELCORPORATION-MULTI-FLEX-SERVER-BLADES-MIB.my that ships with
# firmware updates
STATUSES_OID = ".1.3.6.1.4.1.343.2.19.1.2.10.202.1.1.6"
# Status constants returned as value from SNMP
STATUS_UP = 2
STATUS_DOWN = 0
# Status constants to set as value to SNMP
STATUS_SET_ON = 2
STATUS_SET_OFF = 3
### FUNCTIONS ###
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" % (STATUSES_OID, options["--plug"]),
(options["--action"]=="on" and STATUS_SET_ON or STATUS_SET_OFF))
def get_outlets_status(conn, options):
result = {}
res_blades = conn.walk(STATUSES_OID, 30)
for x in res_blades:
port_num = x[0].split('.')[-1]
port_alias = ""
port_status = (x[1]==str(STATUS_UP) and "on" or "off")
result[port_num] = (port_alias, port_status)
return result
# Main agent method
def main():
device_opt = [ "ipaddr", "login", "passwd", "no_login", "no_password",
"port", "snmp_version", "community" ]
atexit.register(atexit_handler)
snmp_define_defaults ()
options = check_input(device_opt, process_input(device_opt))
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 \
work with MFSYS35 as well). \
\n.P\n\
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."
docs["vendorurl"] = "http://www.intel.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/ipdu/fence_ipdu.py b/fence/agents/ipdu/fence_ipdu.py
index c1fc368b..62a2df45 100644
--- a/fence/agents/ipdu/fence_ipdu.py
+++ b/fence/agents/ipdu/fence_ipdu.py
@@ -1,158 +1,158 @@
-#!/usr/bin/python
+#!/usr/bin/python -tt
# The Following agent has been tested on:
# IBM iPDU model 46M4002
# Firmware release OPDP_sIBM_v01.2_1
#
import sys
import atexit
sys.path.append("/usr/share/fence")
from fencing import *
from fencing_snmp import *
#BEGIN_VERSION_GENERATION
RELEASE_VERSION="IBM iPDU SNMP fence agent"
REDHAT_COPYRIGHT=""
BUILD_DATE=""
#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 IBM iPDU
device = None
# Port ID
port_id = None
# Switch ID
switch_id = None
# Classes describing Device params
class IBMiPDU:
# 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'
outlet_table_oid = '.1.3.6.1.4.1.2.6.223.8.2.2.1.2'
ident_str = "IBM iPDU"
state_on = 1
state_off = 0
turn_on = 1
turn_off = 0
has_switches = False
### FUNCTIONS ###
def ipdu_set_device(conn, options):
global device
agents_dir = {'.1.3.6.1.4.1.2.6.223':IBMiPDU,
None:IBMiPDU}
# 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])))):
pdu_type = [[None, None]]
device = agents_dir[pdu_type[0][1]]
conn.log_command("Trying %s"%(device.ident_str))
def ipdu_resolv_port_id(conn, options):
global port_id, switch_id
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()))):
port_id = int(options["--plug"])
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"]):
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["--plug"]))
def get_power_status(conn, options):
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")
def set_power_status(conn, options):
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))
def get_outlets_status(conn, options):
result = {}
if (device == None):
ipdu_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
# Main agent method
def main():
global device
device_opt = [ "ipaddr", "login", "passwd", "no_login", "no_password", \
"port", "snmp_version", "community" ]
atexit.register(atexit_handler)
snmp_define_defaults ()
all_opt["snmp_version"]["default"] = "3"
all_opt["community"]["default"] = "private"
all_opt["switch"]["default"] = "1"
device = IBMiPDU
options = check_input(device_opt, process_input(device_opt))
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 \
into a device via SNMP and reboots a specified outlet. It supports \
SNMP v3 with all combinations of authenticity/privacy settings."
docs["vendorurl"] = "http://www.ibm.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/ipmilan/fence_ipmilan.py b/fence/agents/ipmilan/fence_ipmilan.py
index 804928b0..b120d6b1 100644
--- a/fence/agents/ipmilan/fence_ipmilan.py
+++ b/fence/agents/ipmilan/fence_ipmilan.py
@@ -1,202 +1,202 @@
-#!/usr/bin/python
+#!/usr/bin/python -tt
import sys, shlex, subprocess, re, os
import logging
import atexit
from pipes import quote
sys.path.append("@FENCEAGENTSLIBDIR@")
from fencing import *
from fencing import SUDO_PATH, LOG_MODE_VERBOSE, fail_usage, is_executable
#BEGIN_VERSION_GENERATION
RELEASE_VERSION=""
REDHAT_COPYRIGHT=""
BUILD_DATE=""
#END_VERSION_GENERATION
def get_power_status(_, options):
cmd = create_command(options, "status")
try:
logging.info("Executing: %s\n" % cmd)
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()
process.stderr.close()
logging.debug("%s\n" % str(out))
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
def set_power_status(_, options):
cmd = create_command(options, options["--action"])
try:
logging.debug("Executing: %s\n" % cmd)
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()
process.stderr.close()
logging.debug("%s\n" % str(out))
return
def reboot_cycle(_, options):
cmd = create_command(options, "cycle")
try:
logging.debug("Executing: %s\n" % cmd)
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()
process.stderr.close()
logging.debug("%s\n" % str(out))
return bool(re.search('chassis power control: cycle', str(out).lower()))
def create_command(options, action):
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"]
# --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"]
# --password / -p
if options.has_key("--password"):
cmd += " -P " + quote(options["--password"])
# --cipher / -C
cmd += " -C " + options["--cipher"]
# --port / -n
if options.has_key("--ipport"):
cmd += " -p " + options["--ipport"]
if options.has_key("--privlvl"):
cmd += " -L " + options["--privlvl"]
# --action / -o
cmd += " chassis power " + action
# --use-sudo / -d
if options.has_key("--use-sudo"):
cmd = SUDO_PATH + " " + 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
}
def main():
atexit.register(atexit_handler)
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"
all_opt["ipport"]["default"] = "623"
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\
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)
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)
if __name__ == "__main__":
main()
diff --git a/fence/agents/ldom/fence_ldom.py b/fence/agents/ldom/fence_ldom.py
index 7545eed4..65c810b0 100644
--- a/fence/agents/ldom/fence_ldom.py
+++ b/fence/agents/ldom/fence_ldom.py
@@ -1,119 +1,119 @@
-#!/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
## 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"
REDHAT_COPYRIGHT=""
BUILD_DATE=""
#END_VERSION_GENERATION
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+"'")
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"]))
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"]))
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(r"^(\S+)\s+(\S+)\s+.*$", line)
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"))
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]
else:
return result
def set_power_status(conn, options):
start_communication(conn, options)
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"]))
def main():
device_opt = [ "ipaddr", "login", "passwd", "cmd_prompt", "secure", "port" ]
atexit.register(atexit_handler)
all_opt["secure"]["default"] = "1"
all_opt["cmd_prompt"]["default"] = [ r"\ $" ]
options = check_input(device_opt, process_input(device_opt))
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 \
so, that run ldm command on host machine. So ldm must be directly \
runnable.\
\n.P\n\
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."
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, get_power_status)
##
## Logout from system
######
try:
conn.send_eol("logout")
conn.close()
except exceptions.OSError:
pass
except pexpect.ExceptionPexpect:
pass
sys.exit(result)
if __name__ == "__main__":
main()
diff --git a/fence/agents/lib/check_used_options.py b/fence/agents/lib/check_used_options.py
index 92a2ae65..ce74fa98 100755
--- a/fence/agents/lib/check_used_options.py
+++ b/fence/agents/lib/check_used_options.py
@@ -1,65 +1,65 @@
-#!/usr/bin/python
+#!/usr/bin/python -tt
## 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)
##
import sys, re
sys.path.append("@FENCEAGENTSLIBDIR@")
from fencing import all_opt
def main():
agent = sys.argv[1]
available = { }
## all_opt from fencing library are imported
for k in all_opt.keys():
if all_opt[k].has_key("longopt"):
available["--" + all_opt[k]["longopt"]] = True
## add UUID which is derived automatically from --plug if possible
available["--uuid"] = True
## all_opt defined in fence agent are found
agent_file = open(agent)
opt_re = re.compile(r"\s*all_opt\[\"([^\"]*)\"\] = {")
opt_longopt_re = re.compile(r"\s*\"longopt\" : \"([^\"]*)\"")
in_opt = False
for line in agent_file:
if opt_re.search(line) != None:
in_opt = True
if in_opt and opt_longopt_re.search(line) != None:
available["--" + opt_longopt_re.search(line).group(1)] = True
in_opt = False
## check if all options are defined
agent_file = open(agent)
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):
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):
print "ERROR on line %d in %s: option %s is not defined" % (counter, agent, option_has_re.search(line).group(1))
without_errors = False
if without_errors:
sys.exit(0)
else:
sys.exit(1)
if __name__ == "__main__":
main()
diff --git a/fence/agents/lib/fencing.py.py b/fence/agents/lib/fencing.py.py
index a5f9ecff..291115f6 100644
--- a/fence/agents/lib/fencing.py.py
+++ b/fence/agents/lib/fencing.py.py
@@ -1,1093 +1,1093 @@
-#!/usr/bin/python
+#!/usr/bin/python -tt
import sys, getopt, time, os, uuid, pycurl, stat
import pexpect, re, atexit, syslog
import logging
import __main__
## do not add code here.
#BEGIN_VERSION_GENERATION
RELEASE_VERSION = "New fence lib agent - test release on steroids"
REDHAT_COPYRIGHT = ""
BUILD_DATE = "March, 2008"
#END_VERSION_GENERATION
__all__ = [ 'atexit_handler', 'check_input', 'process_input', 'all_opt', 'show_docs',
'fence_login', 'fence_action' ]
LOG_MODE_VERBOSE = 100
LOG_MODE_QUIET = 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_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",
"longopt" : "help",
"help" : "-h, --help Display this help and exit",
"required" : "0",
"shortdesc" : "Display help and exit",
"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 },
"verbose" : {
"getopt" : "v",
"longopt" : "verbose",
"help" : "-v, --verbose Verbose mode",
"required" : "0",
"shortdesc" : "Verbose mode",
"order" : 51 },
"debug" : {
"getopt" : "D:",
"longopt" : "debug-file",
"help" : "-D, --debug-file=[debugfile] Debugging to output file",
"required" : "0",
"shortdesc" : "Write debug information to given file",
"order" : 52 },
"delay" : {
"getopt" : "f:",
"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 },
"agent" : {
"getopt" : "",
"help" : "",
"order" : 1 },
"web" : {
"getopt" : "",
"help" : "",
"order" : 1 },
"action" : {
"getopt" : "o:",
"longopt" : "action",
"help" : "-o, --action=[action] Action: status, reboot (default), off or on",
"required" : "1",
"shortdesc" : "Fencing Action",
"default" : "reboot",
"order" : 1 },
"fabric_fencing" : {
"getopt" : "",
"help" : "",
"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 },
"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 },
"login" : {
"getopt" : "l:",
"longopt" : "username",
"help" : "-l, --username=[name] Login name",
"required" : "?",
"shortdesc" : "Login Name",
"order" : 1 },
"no_login" : {
"getopt" : "",
"help" : "",
"order" : 1 },
"no_password" : {
"getopt" : "",
"help" : "",
"order" : 1 },
"no_port" : {
"getopt" : "",
"help" : "",
"order" : 1 },
"passwd" : {
"getopt" : "p:",
"longopt" : "password",
"help" : "-p, --password=[password] Login password or passphrase",
"required" : "0",
"shortdesc" : "Login password or passphrase",
"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 },
"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 },
"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 },
"secure" : {
"getopt" : "x",
"longopt" : "ssh",
"help" : "-x, --ssh Use ssh connection",
"shortdesc" : "SSH connection",
"required" : "0",
"order" : 1 },
"ssh_options" : {
"getopt" : "X:",
"longopt" : "ssh-options",
"help" : "--ssh-options=[options] SSH options to use",
"shortdesc" : "SSH options to use",
"required" : "0",
"order" : 1 },
"ssl" : {
"getopt" : "z",
"longopt" : "ssl",
"help" : "-z, --ssl Use ssl connection",
"required" : "0",
"shortdesc" : "SSL connection",
"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 do not support TLS1.0 and up.",
"required" : "0",
"shortdesc" : "Disable TLS negotiation",
"order" : 1 },
"port" : {
"getopt" : "n:",
"longopt" : "plug",
"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 },
"switch" : {
"getopt" : "s:",
"longopt" : "switch",
"help" : "-s, --switch=[id] Physical switch number on device",
"required" : "0",
"shortdesc" : "Physical switch number on device",
"order" : 1 },
"exec" : {
"getopt" : "e:",
"longopt" : "exec",
"help" : "-e, --exec=[command] Command to execute",
"required" : "0",
"shortdesc" : "Command to execute",
"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 },
"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 },
"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 },
"community" : {
"getopt" : "c:",
"longopt" : "community",
"help" : "-c, --community=[community] Set the community string",
"required" : "0",
"shortdesc" : "Set the community string",
"order" : 1},
"snmp_auth_prot" : {
"getopt" : "b:",
"longopt" : "snmp-auth-prot",
"help" : "-b, --snmp-auth-prot=[prot] Set authentication protocol (MD5|SHA)",
"required" : "0",
"shortdesc" : "Set authentication protocol (MD5|SHA)",
"choices" : [ "MD5" , "SHA" ],
"order" : 1},
"snmp_sec_level" : {
"getopt" : "E:",
"longopt" : "snmp-sec-level",
"help" : "-E, --snmp-sec-level=[level] Set security level\n"+
" (noAuthNoPriv|authNoPriv|authPriv)",
"required" : "0",
"shortdesc" : "Set security level (noAuthNoPriv|authNoPriv|authPriv)",
"choices" : [ "noAuthNoPriv", "authNoPriv", "authPriv" ],
"order" : 1},
"snmp_priv_prot" : {
"getopt" : "B:",
"longopt" : "snmp-priv-prot",
"help" : "-B, --snmp-priv-prot=[prot] Set privacy protocol (DES|AES)",
"required" : "0",
"shortdesc" : "Set privacy protocol (DES|AES)",
"choices" : [ "DES", "AES" ],
"order" : 1},
"snmp_priv_passwd" : {
"getopt" : "P:",
"longopt" : "snmp-priv-passwd",
"help" : "-P, --snmp-priv-passwd=[pass] Set privacy protocol password",
"required" : "0",
"shortdesc" : "Set privacy protocol password",
"order" : 1},
"snmp_priv_passwd_script" : {
"getopt" : "R:",
"longopt" : "snmp-priv-passwd-script",
"help" : "-R, --snmp-priv-passwd-script Script to run to retrieve privacy password",
"required" : "0",
"shortdesc" : "Script to run to retrieve privacy password",
"order" : 1},
"inet4_only" : {
"getopt" : "4",
"longopt" : "inet4-only",
"help" : "-4, --inet4-only Forces agent to use IPv4 addresses only",
"required" : "0",
"shortdesc" : "Forces agent to use IPv4 addresses only",
"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 },
"separator" : {
"getopt" : "C:",
"longopt" : "separator",
"help" : "-C, --separator=[char] Separator for CSV created by 'list' operation",
"default" : ",",
"required" : "0",
"shortdesc" : "Separator for CSV created by operation list",
"order" : 100 },
"login_timeout" : {
"getopt" : "y:",
"longopt" : "login-timeout",
"help" : "--login-timeout=[seconds] Wait X seconds for cmd prompt after login",
"default" : "5",
"required" : "0",
"shortdesc" : "Wait X seconds for cmd prompt after login",
"order" : 200 },
"shell_timeout" : {
"getopt" : "Y:",
"longopt" : "shell-timeout",
"help" : "--shell-timeout=[seconds] Wait X seconds for cmd prompt after issuing command",
"default" : "3",
"required" : "0",
"shortdesc" : "Wait X seconds for cmd prompt after issuing command",
"order" : 200 },
"power_timeout" : {
"getopt" : "g:",
"longopt" : "power-timeout",
"help" : "--power-timeout=[seconds] Test X seconds for status change after ON/OFF",
"default" : "20",
"required" : "0",
"shortdesc" : "Test X seconds for status change after ON/OFF",
"order" : 200 },
"power_wait" : {
"getopt" : "G:",
"longopt" : "power-wait",
"help" : "--power-wait=[seconds] Wait X seconds after issuing ON/OFF",
"default" : "0",
"required" : "0",
"shortdesc" : "Wait X seconds after issuing ON/OFF",
"order" : 200 },
"missing_as_off" : {
"getopt" : "M",
"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 },
"retry_on" : {
"getopt" : "F:",
"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 },
"session_url" : {
"getopt" : "s:",
"longopt" : "session-url",
"help" : "-s, --session-url URL to connect to XenServer on",
"required" : "1",
"shortdesc" : "The URL of the XenServer host.",
"order" : 1},
"sudo" : {
"getopt" : "d",
"longopt" : "use-sudo",
"help" : "--use-sudo Use sudo (without password) when calling 3rd party software",
"required" : "0",
"shortdesc" : "Use sudo (without password) when calling 3rd party sotfware.",
"order" : 205},
"method" : {
"getopt" : "m:",
"longopt" : "method",
"help" : "-m, --method=[method] Method to fence (onoff|cycle) (Default: onoff)",
"required" : "0",
"shortdesc" : "Method to fence (onoff|cycle)",
"default" : "onoff",
"choices" : [ "onoff", "cycle" ],
"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" ]
}
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):
result = self.expect(pattern, timeout)
logging.debug("Received: %s" % (self.before + self.after))
return result
def send(self, message):
logging.debug("Sent: %s" % message)
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"])
def atexit_handler():
try:
sys.stdout.close()
os.close(1)
except IOError:
logging.error("%s failed to close standard output\n" % (sys.argv[0]))
syslog.syslog(syslog.LOG_ERR, "Failed to close standard output")
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])
return added_opt
def fail_usage(message = ""):
if len(message) > 0:
logging.error("%s\n" % message)
logging.error("Please use '-h' for usage\n")
sys.exit(EC_GENERIC_ERROR)
def fail(error_code):
message = {
EC_LOGIN_DENIED : "Unable to connect/login to fencing device",
EC_CONNECTION_LOST : "Connection lost",
EC_TIMED_OUT : "Connection timed out",
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_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"
logging.error("%s\n" % message)
syslog.syslog(syslog.LOG_ERR, message)
sys.exit(EC_GENERIC_ERROR)
def usage(avail_opt):
print "Usage:"
print "\t" + os.path.basename(sys.argv[0]) + " [options]"
print "Options:"
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):
# 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.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 "<longdesc>" + docs["longdesc"] + "</longdesc>"
if docs.has_key("vendorurl"):
print "<vendor-url>" + docs["vendorurl"] + "</vendor-url>"
print "<parameters>"
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("&", "&amp;" )
default = default.replace('"', "&quot;" )
default = default.replace('<', "&lt;" )
default = default.replace('>', "&gt;" )
default = default.replace("'", "&apos;" )
default = "default=\"" + default + "\" "
mixed = all_opt[option]["help"]
## split it between option and help text
res = re.compile(r"^(.*--\S+)\s+", re.IGNORECASE | re.S).search(mixed)
if (None != res):
mixed = res.group(1)
mixed = mixed.replace("<", "&lt;").replace(">", "&gt;")
print "\t\t<getopt mixed=\"" + mixed + "\" />"
if all_opt[option].has_key("choices"):
print "\t\t<content type=\"select\" "+default+" >"
for choice in all_opt[option]["choices"]:
print "\t\t\t<option value=\"%s\" />" % (choice)
print "\t\t</content>"
elif all_opt[option]["getopt"].count(":") > 0:
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\" />"
print "\t<action name=\"status\" />"
print "\t<action name=\"list\" />"
print "\t<action name=\"monitor\" />"
print "\t<action name=\"metadata\" />"
print "</actions>"
print "</resource-agent>"
def process_input(avail_opt):
avail_opt.extend(add_dependency_options(avail_opt))
##
## Set standard environment
#####
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 x in avail_opt and 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
##
#####
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:
logging.warning("Parse error: Ignoring unknown option '%s'\n" % line)
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"
return opt
##
## 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):
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)"
## 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
options["--action"] = options["--action"].lower()
if options.has_key("--verbose"):
logging.getLogger().setLevel(logging.DEBUG)
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
#####
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.has_key("--debug-file"):
try:
fh = logging.FileHandler(options["--debug-file"])
fh.setLevel(logging.DEBUG)
logging.getLogger().addHandler(fh)
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("--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"):
longopt = "--" + all_opt[opt]["longopt"]
possible_values_upper = map (lambda y : y.upper(), 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:
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"])))
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):
status = "off"
if options.has_key("--plugs"):
for plug in options["--plugs"]:
try:
options["--uuid"] = str(uuid.UUID(plug))
except ValueError:
pass
except KeyError:
pass
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"]:
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)
def show_docs(options, docs = None):
device_opt = options["device_opt"]
if docs == None:
docs = { }
docs["shortdesc"] = "Fence agent"
docs["longdesc"] = ""
## Process special options (and exit)
#####
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)
sys.exit(0)
if options.has_key("--version"):
print __main__.RELEASE_VERSION, __main__.BUILD_DATE
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):
result = 0
try:
if options.has_key("--plug"):
options["--plugs"] = options["--plug"].split(",")
## 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
return
status = get_multi_power_fn(tn, options, get_power_fn)
if status != "on" and status != "off":
fail(EC_STATUS)
if options["--action"] == "on":
if status == "on":
print "Success: Already 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)
elif options["--action"] == "off":
if status == "off":
print "Success: Already 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)
elif options["--action"] == "reboot":
power_on = False
if options.has_key("--method") and options["--method"].lower() == "cycle" and reboot_cycle_fn is not None:
for _ in range(1, 1 + int(options["--retry-on"])):
if reboot_cycle_fn(tn, options):
power_on = True
break
if not power_on:
fail(EC_TIMED_OUT)
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:
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
except Exception, ex:
# an error occured during power ON phase in reboot
# fence action was completed succesfully even in that case
logging.error("%s\n", str(ex))
syslog.syslog(syslog.LOG_NOTICE, str(ex))
if power_on == False:
# this should not fail as node was fenced succesfully
logging.error('Timed out waiting to power ON\n')
syslog.syslog(syslog.LOG_NOTICE, "Timed out waiting to power ON")
print "Success: Rebooted"
elif options["--action"] == "status":
print "Status: " + status.upper()
if status.upper() == "OFF":
result = 2
elif options["--action"] == "monitor":
pass
except pexpect.EOF:
fail(EC_CONNECTION_LOST)
except pexpect.TIMEOUT:
fail(EC_TIMED_OUT)
except pycurl.error, ex:
logging.error("%s\n" % str(ex))
syslog.syslog(syslog.LOG_ERR, ex[1])
fail(EC_TIMED_OUT)
return result
def fence_login(options, re_login_string = r"(login\s*: )|(Login Name: )|(username: )|(User Name :)"):
force_ipvx = ""
if (options.has_key("--inet6-only")):
force_ipvx = "-6 "
if (options.has_key("--inet4-only")):
force_ipvx = "-4 "
if (options.has_key("eol") == False):
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"]:
logging.info("Delay %s second(s) before logging in to the fence device" % options["--delay"])
time.sleep(int(options["--delay"]))
try:
re_login = re.compile(re_login_string, re.IGNORECASE)
re_pass = re.compile("(password)|(pass phrase)", re.IGNORECASE)
if options.has_key("--ssl"):
gnutls_opts = ""
if options.has_key("--notls"):
gnutls_opts = "--priority \"NORMAL:-VERS-TLS1.2:-VERS-TLS1.1:-VERS-TLS1.0:+VERS-SSL3.0\""
command = '%s %s --insecure --crlf -p %s %s' % \
(SSL_PATH, gnutls_opts, options["--ipport"], options["--ip"])
try:
conn = fspawn(options, command)
except pexpect.ExceptionPexpect, ex:
logging.error("%s\n" % str(ex))
syslog.syslog(syslog.LOG_ERR, str(ex))
sys.exit(EC_GENERIC_ERROR)
elif options.has_key("--ssh") and 0 == options.has_key("--identity-file"):
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"]
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(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"]))
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"]
conn = fspawn(options, command)
result = conn.log_expect(options, [ "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(options,
[ "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, options["--command-prompt"], int(options["--login-timeout"]))
else:
fail_usage("Failed: You have to enter passphrase (-p) for identity file")
else:
conn = fspawn(options, TELNET_PATH)
conn.send("set binary\n")
conn.send("open %s -%s\n"%(options["--ip"], options["--ipport"]))
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)
except pexpect.EOF:
fail(EC_LOGIN_DENIED)
except pexpect.TIMEOUT:
fail(EC_LOGIN_DENIED)
return conn
def is_executable(path):
if os.path.exists(path):
stats = os.stat(path)
if stat.S_ISREG(stats.st_mode) and os.access(path, os.X_OK):
return True
return False
diff --git a/fence/agents/lib/fencing_snmp.py.py b/fence/agents/lib/fencing_snmp.py.py
index 3709ec84..1cd82318 100644
--- a/fence/agents/lib/fencing_snmp.py.py
+++ b/fence/agents/lib/fencing_snmp.py.py
@@ -1,141 +1,141 @@
-#!/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, LOG_MODE_VERBOSE
__all__ = [ 'FencingSnmp', 'snmp_define_defaults' ]
## do not add code here.
#BEGIN_VERSION_GENERATION
RELEASE_VERSION = ""
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):
logging.debug("%s\n" % message)
def quote_for_run(self, string):
return ''.join(map(lambda x:x==r"'" and "'\\''" or x, string))
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"'
]]
for val in mapping:
e = val[0]
res = True
for item in e:
if ((item[0]=='!') and (self.options.has_key("--"+item[1:]))):
res = False
break
if ((item[0]!='!') and (not self.options.has_key("--"+item[0:]))):
res = False
break
if res:
exec(val[1])
def prepare_cmd(self, command):
cmd = "@SNMPBIN@/%s -m '' -Oeqn "% (command)
self.complete_missed_params()
#mapping from our option to snmpcmd option
mapping = (('snmp-version', 'v'),('community', 'c'))
for item in mapping:
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'))
for item in mapping_v3:
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")):
force_ipvx = "udp6:"
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 "")
return cmd
def run_command(self, command, additional_timemout=0):
try:
self.log_command(command)
(res_output, res_code) = pexpect.run(command,
int(self.options["--shell-timeout"]) +
int(self.options["--login-timeout"]) +
additional_timemout, True)
if (res_code==None):
fail(EC_TIMED_OUT)
self.log_command(res_output)
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))
return res_output
def get(self, oid, additional_timemout=0):
cmd = "%s '%s'"% (self.prepare_cmd("snmpget"), self.quote_for_run(oid))
output = self.run_command(cmd, additional_timemout).splitlines()
return output[len(output)-1].split(None, 1)
def set(self, oid, value, additional_timemout=0):
mapping = ((int, 'i'), (str, 's'))
type_of_value = ''
for item in mapping:
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)))
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))
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))
diff --git a/fence/agents/lib/transfer.py b/fence/agents/lib/transfer.py
index ddf2486e..b7a39dbb 100755
--- a/fence/agents/lib/transfer.py
+++ b/fence/agents/lib/transfer.py
@@ -1,16 +1,16 @@
-#!/usr/bin/python
+#!/usr/bin/python -tt
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/fence_lpar.py b/fence/agents/lpar/fence_lpar.py
index 630b2ca3..304ebe41 100644
--- a/fence/agents/lpar/fence_lpar.py
+++ b/fence/agents/lpar/fence_lpar.py
@@ -1,164 +1,164 @@
-#!/usr/bin/python
+#!/usr/bin/python -tt
#####
##
## The Following Agent Has Been Tested On:
##
## Version
## +---------------------------------------------+
## Tested on HMC
##
#####
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=""
REDHAT_COPYRIGHT=""
BUILD_DATE=""
#END_VERSION_GENERATION
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"]))
try:
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"]))
try:
status = re.compile(",state=(.*?),", re.IGNORECASE).search(conn.before).group(1)
except AttributeError:
fail(EC_STATUS_HMC)
##
## Transformation to standard ON/OFF status if possible
if status in ["Running", "Open Firmware", "Shutting Down", "Starting"]:
status = "on"
else:
status = "off"
return status
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"]))
elif options["--hmc-version"] == "4":
if options["--action"] == "on":
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" )
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"]))
def get_lpar_list(conn, options):
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"]))
## We have to remove first 3 lines (command + header) and last line (part of new prompt)
####
res = re.search("^.+?\n(.+?\n){2}(.*)\n.*$", conn.before, re.S)
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"] +
" -F name:state\n")
conn.log_expect(options, options["--command-prompt"], int(options["--power-timeout"]))
## We have to remove first line (command) and last line (part of new prompt)
####
res = re.search("^.+?\n(.*)\n.*$", conn.before, re.S)
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(":")
outlets[port] = ("", status)
return outlets
def define_new_opts():
all_opt["managed"] = {
"getopt" : "s:",
"longopt" : "managed",
"help" : "-s, --managed=[id] Name of the managed system",
"required" : "0",
"shortdesc" : "Managed system name",
"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 }
def main():
device_opt = [ "ipaddr", "login", "passwd", "secure", "cmd_prompt", \
"port", "managed", "hmc_version" ]
atexit.register(atexit_handler)
define_new_opts()
all_opt["login_timeout"]["default"] = "15"
all_opt["secure"]["default"] = "1"
all_opt["cmd_prompt"]["default"] = [ r":~>", r"]\$", r"\$ " ]
options = check_input(device_opt, process_input(device_opt))
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"):
fail_usage("Failed: You have to enter name of managed system")
##
## 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
sys.exit(result)
if __name__ == "__main__":
main()
diff --git a/fence/agents/netio/fence_netio.py b/fence/agents/netio/fence_netio.py
index a1b4abf8..4708ff6c 100755
--- a/fence/agents/netio/fence_netio.py
+++ b/fence/agents/netio/fence_netio.py
@@ -1,115 +1,115 @@
-#!/usr/bin/python
+#!/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, TELNET_PATH
#BEGIN_VERSION_GENERATION
RELEASE_VERSION=""
REDHAT_COPYRIGHT=""
BUILD_DATE=""
#END_VERSION_GENERATION
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"]))
status = {
"0" : "off",
"1" : "on",
"i" : "reboot",
"m" : "manual",
"t" : "timer"
}[conn.after.split()[1]]
return status
def set_power_status(conn, options):
action = {
"on" : "1",
"off" : "0",
"reboot" : "i"
}[options["--action"]]
conn.send_eol("port %s %s" % (options["--plug"], action))
conn.log_expect(options, "250 OK", int(options["--shell-timeout"]))
def get_outlet_list(conn, options):
result = {}
try:
# 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"]))
# the name is enclosed in "", drop those with [1:-1]
name = conn.after.split()[1][1:-1]
result[plug] = (name, "unknown")
except Exception, exn:
print str(exn)
return result
def main():
device_opt = [ "ipaddr", "login", "passwd", "port" ]
atexit.register(atexit_handler)
opt = process_input(device_opt)
# set default port for telnet only
if 0 == opt.has_key("--ipport"):
opt["--ipport"] = "1234"
opt["eol"] = "\r\n"
options = check_input(device_opt, opt)
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 \
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.koukaam.se/"
show_docs(options, docs)
##
## Operate the fencing device
## We can not use fence_login(), username and passwd are sent on one line
####
try:
conn = fspawn(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(options, "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"]))
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
sys.exit(result)
if __name__ == "__main__":
main()
diff --git a/fence/agents/ovh/fence_ovh.py b/fence/agents/ovh/fence_ovh.py
index c57ed86b..cd33b171 100644
--- a/fence/agents/ovh/fence_ovh.py
+++ b/fence/agents/ovh/fence_ovh.py
@@ -1,148 +1,148 @@
-#!/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
# Based on:
# This is a fence agent for use at OVH
# As there are no other fence devices available, we must use OVH's SOAP API #Quick-and-dirty
# assemled by Dennis Busch, secofor GmbH, Germany
# This work is licensed under a Creative Commons Attribution-ShareAlike 3.0 Unported License.
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
OVH_RESCUE_PRO_NETBOOT_ID = '28'
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
def define_new_opts():
all_opt["email"] = {
"getopt" : "Z:",
"longopt" : "email",
"help" : "-Z, --email=<email> email for reboot message: admin@domain.com",
"required" : "1",
"shortdesc" : "Reboot email",
"default" : "",
"order" : 1 }
def netboot_reboot(options, mode):
conn = soap_login(options)
# 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.logout(options["session"])
def reboot_time(options):
conn = soap_login(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')
result.start = tmpstart
result.end = tmpend
conn.logout(options["session"])
return result
def soap_login(options):
imp = Import('http://schemas.xmlsoap.org/soap/encoding/')
url = 'https://www.ovh.com/soapi/soapi-re-1.59.wsdl'
imp.filter.add('http://soapi.ovh.com/manager')
d = ImportDoctor(imp)
tmp_dir = tempfile.mkdtemp()
tempfile.tempdir = tmp_dir
atexit.register(remove_tmp_dir, tmp_dir)
try:
soap = Client(url, doctor=d)
session = soap.service.login(options["--username"], options["--password"], 'en', 0)
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" ]
atexit.register(atexit_handler)
define_new_opts()
options = check_input(device_opt, process_input(device_opt))
docs = { }
docs["shortdesc"] = "Fence agent for OVH"
docs["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."
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["--plug"].endswith(".ovh.net") == False:
options["--plug"] += ".ovh.net"
if options.has_key("--email") == False:
fail_usage("You have to enter e-mail address which is notified by fence agent")
# 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)
time.sleep(STATUS_RESCUE_PRO_SLEEP)
elif options["--action"] in ['on', 'reboot' ]:
# Reboot from HD
netboot_reboot(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)
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
logging.debug("Netboot reboot went OK.\n")
else:
result = 1
logging.debug("ERROR: Netboot reboot wasn't OK.\n")
sys.exit(result)
if __name__ == "__main__":
main()
diff --git a/fence/agents/rhevm/fence_rhevm.py b/fence/agents/rhevm/fence_rhevm.py
index 807084d1..c8760d97 100644
--- a/fence/agents/rhevm/fence_rhevm.py
+++ b/fence/agents/rhevm/fence_rhevm.py
@@ -1,129 +1,129 @@
-#!/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, LOG_MODE_VERBOSE
#BEGIN_VERSION_GENERATION
RELEASE_VERSION="New RHEV-M Agent - test release on steroids"
REDHAT_COPYRIGHT=""
BUILD_DATE="March, 2008"
#END_VERSION_GENERATION
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)
def get_power_status(conn, options):
### Obtain real ID from name
res = send_command(options, "vms/?search=name%3D" + options["--plug"])
result = RE_GET_ID.search(res)
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):
# 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
return "off"
else:
status = result.group(1)
if (status.lower() == "down"):
return "off"
else:
return "on"
def set_power_status(conn, options):
action = {
'on' : "start",
'off' : "stop"
}[options["--action"]]
url = "vms/" + options["id"] + "/" + action
send_command(options, url, "POST")
def get_list(conn, options):
outlets = { }
try:
res = send_command(options, "vms")
lines = res.split("<vm ")
for i in range(1, len(lines)):
name = RE_GET_NAME.search(lines[i]).group(1)
outlets[name] = ("", None)
except AttributeError:
return { }
except IndexError:
return { }
return outlets
def send_command(opt, command, method = "GET"):
## setup correct URL
if opt.has_key("--ssl"):
url = "https:"
else:
url = "http:"
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()
logging.debug("%s\n" % command)
logging.debug("%s\n" % result)
return result
def main():
device_opt = [ "ipaddr", "login", "passwd", "ssl", "notls", "web", "port" ]
atexit.register(atexit_handler)
all_opt["power_wait"]["default"] = "1"
options = check_input(device_opt, process_input(device_opt))
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."
docs["vendorurl"] = "http://www.redhat.com"
show_docs(options, docs)
##
## Fence operations
####
result = fence_action(None, options, set_power_status, get_power_status, get_list)
sys.exit(result)
if __name__ == "__main__":
main()
diff --git a/fence/agents/rsa/fence_rsa.py b/fence/agents/rsa/fence_rsa.py
index 4e855a24..ba937092 100644
--- a/fence/agents/rsa/fence_rsa.py
+++ b/fence/agents/rsa/fence_rsa.py
@@ -1,78 +1,78 @@
-#!/usr/bin/python
+#!/usr/bin/python -tt
#####
##
## The Following Agent Has Been Tested On:
## Main GFEP25A & Boot GFBP25A
##
#####
import sys, re
import atexit
sys.path.append("@FENCEAGENTSLIBDIR@")
from fencing import *
#BEGIN_VERSION_GENERATION
RELEASE_VERSION="New RSA2 Agent - test release on steroids"
REDHAT_COPYRIGHT=""
BUILD_DATE=""
#END_VERSION_GENERATION
def get_power_status(conn, options):
conn.send_eol("power state")
conn.log_expect(options, options["--command-prompt"], int(options["--shell-timeout"]))
match = re.compile("Power: (.*)", re.IGNORECASE).search(conn.before)
if (match != None):
status = match.group(1)
else:
status = "undefined"
return status.lower().strip()
def set_power_status(conn, options):
conn.send_eol("power " + options["--action"])
conn.log_expect(options, options["--command-prompt"], int(options["--power-timeout"]))
def main():
device_opt = [ "ipaddr", "login", "passwd", "cmd_prompt", "secure" ]
atexit.register(atexit_handler)
all_opt["login_timeout"]["default"] = 10
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["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 \
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."
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
sys.exit(result)
if __name__ == "__main__":
main()
diff --git a/fence/agents/rsb/fence_rsb.py b/fence/agents/rsb/fence_rsb.py
index af3a2e45..b72d295a 100755
--- a/fence/agents/rsb/fence_rsb.py
+++ b/fence/agents/rsb/fence_rsb.py
@@ -1,87 +1,87 @@
-#!/usr/bin/python
+#!/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("2")
conn.log_expect(options, 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"]))
return (status.lower().strip())
def set_power_status(conn, options):
action = {
'on' : "4",
'off': "1"
}[options["--action"]]
conn.send("2")
conn.log_expect(options, 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.send_eol("yes")
conn.log_expect(options, "any key to continue", int(options["--power-timeout"]))
conn.send_eol("")
conn.log_expect(options, options["--command-prompt"], int(options["--shell-timeout"]))
conn.send_eol("0")
conn.log_expect(options, options["--command-prompt"], int(options["--shell-timeout"]))
def main():
device_opt = [ "ipaddr", "login", "passwd", "secure", "cmd_prompt" ]
atexit.register(atexit_handler)
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"
options = check_input(device_opt, opt)
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 \
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."
docs["vendorurl"] = "http://www.fujitsu.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
##
## 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
sys.exit(result)
if __name__ == "__main__":
main()
diff --git a/fence/agents/sanbox2/fence_sanbox2.py b/fence/agents/sanbox2/fence_sanbox2.py
index e2c944b2..161e002f 100644
--- a/fence/agents/sanbox2/fence_sanbox2.py
+++ b/fence/agents/sanbox2/fence_sanbox2.py
@@ -1,156 +1,156 @@
-#!/usr/bin/python
+#!/usr/bin/python -tt
#####
##
## The Following Agent Has Been Tested On:
##
## Version Firmware
## +-----------------+---------------------------+
#####
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"
REDHAT_COPYRIGHT=""
BUILD_DATE="March, 2008"
#END_VERSION_GENERATION
def get_power_status(conn, options):
status_trans = {
'online' : "on",
'offline' : "off"
}
try:
conn.send_eol("show port " + options["--plug"])
conn.log_expect(options, options["--command-prompt"], int(options["--shell-timeout"]))
except pexpect.TIMEOUT:
try:
conn.send_eol("admin end")
conn.send_eol("exit")
conn.close()
except:
pass
fail(EC_TIMED_OUT)
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()]
except KeyError:
return "PROBLEM"
def set_power_status(conn, options):
action = {
'on' : "online",
'off' : "offline"
}[options["--action"]]
try:
conn.send_eol("set port " + options["--plug"] + " state " + action)
conn.log_expect(options, options["--command-prompt"], int(options["--power-timeout"]))
except pexpect.TIMEOUT:
try:
conn.send_eol("admin end")
conn.send_eol("exit")
conn.close()
except:
pass
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"]))
except pexpect.TIMEOUT:
try:
conn.send_eol("admin end")
conn.send_eol("exit")
conn.close()
except:
pass
fail(EC_TIMED_OUT)
def get_list_devices(conn, options):
outlets = { }
try:
conn.send_eol("show port")
conn.log_expect(options, options["--command-prompt"], int(options["--shell-timeout"]))
list_re = re.compile(r"^\s+(\d+?)\s+(Online|Offline)\s+", re.IGNORECASE)
for line in conn.before.splitlines():
if (list_re.search(line)):
status = {
'online' : "ON",
'offline' : "OFF"
}[list_re.search(line).group(2).lower()]
outlets[list_re.search(line).group(1)] = ("", status)
except pexpect.TIMEOUT:
try:
conn.send_eol("admin end")
conn.send_eol("exit")
conn.close()
except:
pass
fail(EC_TIMED_OUT)
return outlets
def main():
device_opt = [ "fabric_fencing", "ipaddr", "login", "passwd", "cmd_prompt", "port" ]
atexit.register(atexit_handler)
all_opt["cmd_prompt"]["default"] = [ " #> " ]
options = check_input(device_opt, process_input(device_opt))
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 \
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."
docs["vendorurl"] = "http://www.qlogic.com"
show_docs(options, docs)
##
## Operate the fencing device
##
conn = fence_login(options)
conn.send_eol("admin start")
conn.log_expect(options, options["--command-prompt"], int(options["--shell-timeout"]))
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
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)
##
## Logout from system
######
try:
conn.send_eol("admin end")
conn.send_eol("exit\n")
conn.close()
except exceptions.OSError:
pass
except pexpect.ExceptionPexpect:
pass
sys.exit(result)
if __name__ == "__main__":
main()
diff --git a/fence/agents/virsh/fence_virsh.py b/fence/agents/virsh/fence_virsh.py
index f03ea74e..c1cbc65e 100644
--- a/fence/agents/virsh/fence_virsh.py
+++ b/fence/agents/virsh/fence_virsh.py
@@ -1,106 +1,106 @@
-#!/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
import time
import atexit
sys.path.append("@FENCEAGENTSLIBDIR@")
from fencing import *
from fencing import fail_usage, SUDO_PATH
#BEGIN_VERSION_GENERATION
RELEASE_VERSION="Virsh fence agent"
REDHAT_COPYRIGHT=""
BUILD_DATE=""
#END_VERSION_GENERATION
def get_name_or_uuid(options):
return options["--uuid"] if options.has_key("--uuid") else options["--plug"]
def get_outlets_status(conn, options):
if options.has_key("--use-sudo"):
prefix = SUDO_PATH + " "
else:
prefix = ""
conn.sendline(prefix + "virsh list --all")
conn.log_expect(options, options["--command-prompt"], int(options["--shell-timeout"]))
result = {}
#This is status of mini finite automata. 0 = we didn't found Id and Name, 1 = we did
fa_status = 0
for line in conn.before.splitlines():
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")):
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"))
return result
def get_power_status(conn, options):
prefix = 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"]))
for line in conn.before.splitlines():
if line.strip() in ["running", "blocked", "idle", "no state", "paused"]:
return "on"
if "error:" in line.strip():
fail_usage("Failed: You have to enter existing name/UUID of virtual machine!")
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))
conn.log_expect(options, 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" ]
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\"'"
options = check_input(device_opt, process_input(device_opt))
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. \
It logs via ssh to a dom0 and there run virsh command, which does \
all work. \
\n.P\n\
By default, virsh needs root account to do properly work. So you \
must allow ssh login in your sshd_config."
docs["vendorurl"] = "http://libvirt.org"
show_docs(options, docs)
## 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
sys.exit(result)
if __name__ == "__main__":
main()
diff --git a/fence/agents/vmware/fence_vmware.py b/fence/agents/vmware/fence_vmware.py
index 79f58b1f..f645650c 100644
--- a/fence/agents/vmware/fence_vmware.py
+++ b/fence/agents/vmware/fence_vmware.py
@@ -1,340 +1,340 @@
-#!/usr/bin/python
+#!/usr/bin/python -tt
#
# The Following agent has been tested on:
# vmrun 2.0.0 build-116503 (from VMware Server 2.0) against:
# VMware ESX 4.0.0
# VMware vCenter 4.0.0
# VMware ESX 3.5
# VMware Server 2.0.0
# VMware ESXi 3.5 update 2
# VMware Server 1.0.7 (works but list/status show only running VMs)
#
# VI Perl API 1.6 against:
# VMware ESX 4.0.0
# VMware vCenter 4.0.0
# VMware ESX 3.5
# VMware ESXi 3.5 update 2
# VMware Virtual Center 2.5
#
# VMware vSphere SDK for Perl 4.0.0 against:
# VMware ESX 4.0.0
# VMware vCenter 4.0.0
#
import sys, re, pexpect
import logging
import atexit
sys.path.append("@FENCEAGENTSLIBDIR@")
from fencing import *
from fencing import fail, fail_usage, EC_TIMED_OUT, LOG_MODE_VERBOSE
#BEGIN_VERSION_GENERATION
RELEASE_VERSION="VMware Agent using VI Perl API and/or VIX vmrun command"
REDHAT_COPYRIGHT=""
BUILD_DATE=""
#END_VERSION_GENERATION
### CONSTANTS ####
# VMware type is ESX/ESXi/VC
VMWARE_TYPE_ESX = 0
# VMware type is Server 1.x
VMWARE_TYPE_SERVER1 = 1
# VMware type is Server 2.x and/or ESX 3.5 up2, ESXi 3.5 up2, VC 2.5 up2
VMWARE_TYPE_SERVER2 = 2
# Minimum required version of vmrun command
VMRUN_MINIMUM_REQUIRED_VERSION = 2
# Default path to vmhelper command
VMHELPER_COMMAND = "fence_vmware_helper"
# Default path to vmrun command
VMRUN_COMMAND = "/usr/bin/vmrun"
# Default type of vmware
VMWARE_DEFAULT_TYPE = "esx"
#### GLOBAL VARIABLES ####
# Internal type. One of VMWARE_TYPE_, set by #vmware_check_vmware_type
vmware_internal_type = VMWARE_TYPE_ESX
# If ESX is disconnected, say, that VM is off (don't return previous state)
vmware_disconnected_hack = False
### FUNCTIONS ####
#Split string in simplified DSV format to array of items
def dsv_split(dsv_str):
delimiter_c = ':'
escape_c = '\\'
res = []
status = 0
tmp_str = ""
for x in dsv_str:
if (status==0):
if (x==delimiter_c):
res.append(tmp_str)
tmp_str = ""
elif (x==escape_c):
status = 1
else:
tmp_str += x
elif (status==1):
if (x==delimiter_c):
tmp_str += delimiter_c
elif (x==escape_c):
tmp_str += escape_c
else:
tmp_str += escape_c+x
status = 0
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(text):
dstr = ''
for c in text:
if c == r"'":
dstr += "'\\''"
else:
dstr += c
return dstr
# Return string with command and additional parameters (something like vmrun -h 'host'
def vmware_prepare_command(options, add_login_params, additional_params):
res = options["--exec"]
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):
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):
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):
res += "-P '%s' "% (quote_for_run(host_name_array[1]))
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 != ""):
res += additional_params
return res
# Log message if user set verbose option
def vmware_log(options, message):
logging.debug("%s\n" % message)
# 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).
def vmware_run_command(options, add_login_params, additional_params, additional_timeout):
command = vmware_prepare_command(options, add_login_params, additional_params)
try:
vmware_log(options, command)
(res_output, res_code) = pexpect.run(command,
int(options["--shell-timeout"]) + int(options["--login-timeout"]) + additional_timeout, True)
if (res_code==None):
fail(EC_TIMED_OUT)
if ((res_code!=0) and (add_login_params)):
vmware_log(options, res_output)
fail_usage("%s returned %s"% (options["--exec"], res_output))
else:
vmware_log(options, res_output)
except pexpect.ExceptionPexpect:
fail_usage("Cannot run command %s"% (options["--exec"]))
return res_output
# 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):
outlets = {}
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"]))
all_machines_array = all_machines.splitlines()
for machine in all_machines_array:
machine_array = dsv_split(machine)
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):
outlets[machine_array[0]] = ("", (
((machine_array[2].lower() in ["poweredon"]) and
(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):
outlets = {}
running_machines = vmware_run_command(options, True, "list", 0)
running_machines_array = running_machines.splitlines()[1:]
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):
all_machines_array = running_machines_array
for machine in all_machines_array:
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)
def get_power_status(conn, options):
if (vmware_internal_type==VMWARE_TYPE_ESX):
outlets = vmware_get_outlets_vi(conn, 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)):
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")
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"):
additional_params += " hard"
vmware_run_command(options, True, additional_params, int(options["--power-timeout"]))
# 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(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):
return False
except Exception:
return False
return True
# Check vmware type, set vmware_internal_type to one of VMWARE_TYPE_ value and
# options["--exec"] to path (if not specified)
def vmware_check_vmware_type(options):
global vmware_internal_type
options["--vmware_type"] = options["--vmware_type"].lower()
if (options["--vmware_type"]=="esx"):
vmware_internal_type = VMWARE_TYPE_ESX
if (not options.has_key("--exec")):
options["--exec"] = VMHELPER_COMMAND
elif (options["--vmware_type"]=="server2"):
vmware_internal_type = VMWARE_TYPE_SERVER2
if (not options.has_key("--exec")):
options["--exec"] = VMRUN_COMMAND
elif (options["--vmware_type"]=="server1"):
vmware_internal_type = VMWARE_TYPE_SERVER1
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",
"exec", "vmware_type", "vmware_datacenter"]
atexit.register(atexit_handler)
all_opt["secure"]["default"] = "1"
all_opt["vmware_type"]["default"] = VMWARE_DEFAULT_TYPE
options = check_input(device_opt, process_input(device_opt))
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 \
to fence virtual machines.\
\n.P\n\
Before you can use this agent, it must be installed VI Perl Toolkit or \
vmrun command on every node you want to make fencing.\
\n.P\n\
VI Perl Toolkit is preferred for VMware ESX/ESXi and Virtual Center. Vmrun \
command is only solution for VMware Server 1/2 (this command will works against \
ESX/ESXi 3.5 up2 and VC up2 too, but not cluster aware!) and is available as part \
of VMware VIX API SDK package. VI Perl and VIX API SDK are both available from \
VMware web pages (not int RHEL repository!). \
\n.P\n\
You can specify type of VMware you are connecting to with \\fB-d\\fP switch \
(or \\fIvmware_type\\fR for stdin). Possible values are esx, server2 and server1.\
Default value is esx, which will use VI Perl. With server1 and server2, vmrun \
command is used.\
\n.P\n\
After you have successfully installed VI Perl Toolkit or VIX API, you should \
be able to run fence_vmware_helper (part of this agent) or vmrun command. \
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)
# 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))
# Operate the fencing device
result = fence_action(None, options, set_power_status, get_power_status, get_outlets_status)
sys.exit(result)
if __name__ == "__main__":
main()
diff --git a/fence/agents/vmware_soap/fence_vmware_soap.py b/fence/agents/vmware_soap/fence_vmware_soap.py
index f944a04f..ccdbac19 100644
--- a/fence/agents/vmware_soap/fence_vmware_soap.py
+++ b/fence/agents/vmware_soap/fence_vmware_soap.py
@@ -1,227 +1,227 @@
-#!/usr/bin/python
+#!/usr/bin/python -tt
import sys, time
import shutil, tempfile, suds
import logging
import atexit
sys.path.append("@FENCEAGENTSLIBDIR@")
from suds.client import Client
from suds.sudsobject import Property
from fencing import *
from fencing import fail, EC_STATUS, EC_LOGIN_DENIED, EC_INVALID_PRIVILEGES, EC_WAITING_ON, EC_WAITING_OFF
#BEGIN_VERSION_GENERATION
RELEASE_VERSION="New VMWare Agent - test release on steroids"
REDHAT_COPYRIGHT=""
BUILD_DATE="April, 2011"
#END_VERSION_GENERATION
def soap_login(options):
if options["--action"] in ["off", "reboot"]:
time.sleep(int(options["--delay"]))
if options.has_key("--ssl"):
url = "https://"
else:
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)
mo_ServiceInstance = Property('ServiceInstance')
mo_ServiceInstance._type = 'ServiceInstance'
ServiceContent = conn.service.RetrieveServiceContent(mo_ServiceInstance)
mo_SessionManager = Property(ServiceContent.sessionManager.value)
mo_SessionManager._type = 'SessionManager'
conn.service.Login(mo_SessionManager, options["--username"], options["--password"])
except Exception:
fail(EC_LOGIN_DENIED)
options["ServiceContent"] = ServiceContent
options["mo_SessionManager"] = mo_SessionManager
return conn
def process_results(results, machines, uuid, mappingToUUID):
for m in results.objects:
info = {}
for i in m.propSet:
info[i.name] = i.val
# Prevent error KeyError: 'config.uuid' when reaching systems which P2V failed,
# since these systems don't have a valid UUID
if info.has_key("config.uuid"):
machines[info["name"]] = (info["config.uuid"], info["summary.runtime.powerState"])
uuid[info["config.uuid"]] = info["summary.runtime.powerState"]
mappingToUUID[m.obj.value] = info["config.uuid"]
return (machines, uuid, mappingToUUID)
def get_power_status(conn, options):
mo_ViewManager = Property(options["ServiceContent"].viewManager.value)
mo_ViewManager._type = "ViewManager"
mo_RootFolder = Property(options["ServiceContent"].rootFolder.value)
mo_RootFolder._type = "Folder"
mo_PropertyCollector = Property(options["ServiceContent"].propertyCollector.value)
mo_PropertyCollector._type = 'PropertyCollector'
ContainerView = conn.service.CreateContainerView(mo_ViewManager, recursive = 1,
container = mo_RootFolder, type = ['VirtualMachine'])
mo_ContainerView = Property(ContainerView.value)
mo_ContainerView._type = "ContainerView"
FolderTraversalSpec = conn.factory.create('ns0:TraversalSpec')
FolderTraversalSpec.name = "traverseEntities"
FolderTraversalSpec.path = "view"
FolderTraversalSpec.skip = False
FolderTraversalSpec.type = "ContainerView"
objSpec = conn.factory.create('ns0:ObjectSpec')
objSpec.obj = mo_ContainerView
objSpec.selectSet = [ FolderTraversalSpec ]
objSpec.skip = True
propSpec = conn.factory.create('ns0:PropertySpec')
propSpec.all = False
propSpec.pathSet = ["name", "summary.runtime.powerState", "config.uuid"]
propSpec.type = "VirtualMachine"
propFilterSpec = conn.factory.create('ns0:PropertyFilterSpec')
propFilterSpec.propSet = [ propSpec ]
propFilterSpec.objectSet = [ objSpec ]
try:
raw_machines = conn.service.RetrievePropertiesEx(mo_PropertyCollector, propFilterSpec)
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):
try:
raw_machines = conn.service.ContinueRetrievePropertiesEx(mo_PropertyCollector, raw_machines.token)
except Exception:
fail(EC_STATUS)
(more_machines, more_uuid, more_mappingToUUID) = process_results(raw_machines, {}, {}, {})
machines.update(more_machines)
uuid.update(more_uuid)
mappingToUUID.update(more_mappingToUUID)
# Do not run unnecessary SOAP requests
if options.has_key("--uuid") and options["--uuid"] in uuid:
break
if ["list", "monitor"].count(options["--action"]) == 1:
return machines
else:
if options.has_key("--uuid") == False:
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:
fail(EC_STATUS)
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:
fail(EC_STATUS)
except AttributeError:
fail(EC_STATUS)
try:
if uuid[options["--uuid"]] == "poweredOn":
return "on"
else:
return "off"
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"])
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):
fail(EC_INVALID_PRIVILEGES)
else:
if options["--action"] == "on":
fail(EC_WAITING_ON)
else:
fail(EC_WAITING_OFF)
def remove_tmp_dir(tmp_dir):
shutil.rmtree(tmp_dir)
def main():
device_opt = [ "ipaddr", "login", "passwd", "web", "ssl", "notls", "port" ]
atexit.register(atexit_handler)
options = check_input(device_opt, process_input(device_opt))
##
## Fence agent specific defaults
#####
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 \
that have SOAP API v4.1+. \
\n.P\n\
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."
docs["vendorurl"] = "http://www.vmware.com"
show_docs(options, docs)
logging.basicConfig(level=logging.INFO)
logging.getLogger('suds.client').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)
##
## Logout from system
#####
try:
conn.service.Logout(options["mo_SessionManager"])
except Exception:
pass
sys.exit(result)
if __name__ == "__main__":
main()
diff --git a/fence/agents/wti/fence_wti.py b/fence/agents/wti/fence_wti.py
index da68b667..01667fcf 100644
--- a/fence/agents/wti/fence_wti.py
+++ b/fence/agents/wti/fence_wti.py
@@ -1,243 +1,243 @@
-#!/usr/bin/python
+#!/usr/bin/python -tt
#####
##
## The Following Agent Has Been Tested On:
##
## Version Firmware
## +-----------------+---------------------------+
## WTI RSM-8R4 ?? unable to find out ??
## WTI MPC-??? ?? unable to find out ??
## WTI IPS-800-CE v1.40h (no username) ('list' tested)
#####
import sys, re, pexpect
import atexit
import time
sys.path.append("@FENCEAGENTSLIBDIR@")
from fencing import *
from fencing import fspawn, fail, fail_usage, TELNET_PATH, EC_LOGIN_DENIED
#BEGIN_VERSION_GENERATION
RELEASE_VERSION="New WTI Agent - test release on steroids"
REDHAT_COPYRIGHT=""
BUILD_DATE="March, 2008"
#END_VERSION_GENERATION
def get_listing(conn, options, listing_command):
listing = ""
conn.send(listing_command + "\r\n")
if isinstance(options["--command-prompt"], list):
re_all = list(options["--command-prompt"])
else:
re_all = [options["--command-prompt"]]
re_next = re.compile("Enter: ", re.IGNORECASE)
re_all.append(re_next)
result = conn.log_expect(options, 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"]))
listing += conn.before
return listing
def get_plug_status(conn, options):
listing = get_listing(conn, options, "/S")
plug_section = 0
plug_index = -1
name_index = -1
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]:
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):
plug_section = 2
elif (line.upper().startswith("PLUG")):
plug_section = 1
plug_header = [x.strip().lower() for x in line.split("|")]
plug_index = plug_header.index("plug")
name_index = plug_header.index("name")
status_index = plug_header.index("status")
if ["list", "monitor"].count(options["--action"]) == 1:
return outlets
else:
return "PROBLEM"
def get_plug_group_status_from_list(status_list):
for status in status_list:
if status == "on":
return status
return "off"
def get_plug_group_status(conn, options):
listing = get_listing(conn, options, "/SG")
outlets = {}
line_index = 0
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):
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]:
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]):
## 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])
line_index += 1
else:
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:
group_name = plug_line[0]
plug_line_index = line_index + 1
plug_status = []
while plug_line_index < len(lines) and plug_line_index >= 0:
plug_line = [x.strip().lower() for x in lines[plug_line_index].split("|")]
if len(plug_line[name_index]) > 0:
plug_line_index = -1
break
if len(plug_line[plug_index]) > 0:
plug_status.append(plug_line[status_index])
plug_line_index += 1
else:
plug_line_index = -1
outlets[group_name] = (group_name, get_plug_group_status_from_list(plug_status))
line_index += 1
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")
status_index = plug_header.index("status")
line_index += 2
else:
line_index += 1
if ["list", "monitor"].count(options["--action"]) == 1:
for group, status in outlet_groups:
outlets[group] = (group, status[0])
return outlets
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)
return ret
def set_power_status(conn, options):
action = {
'on' : "/on",
'off': "/off"
}[options["--action"]]
conn.send(action + " " + options["--plug"] + ",y\r\n")
conn.log_expect(options, options["--command-prompt"], int(options["--power-timeout"]))
def main():
device_opt = [ "ipaddr", "login", "passwd", "no_login", "no_password", \
"cmd_prompt", "secure", "port" ]
atexit.register(atexit_handler)
all_opt["cmd_prompt"]["default"] = [ "RSM>", "MPC>", "IPS>", "TPS>", "NBB>", "NPS>", "VMR>" ]
options = check_input(device_opt, process_input(device_opt))
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 \
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."
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"):
try:
if options["--action"] in ["off", "reboot"]:
time.sleep(int(options["--delay"]))
conn = fspawn(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)
result = conn.log_expect(options, [ 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"]))
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"]))
else:
fail_usage("Failed: You have to enter password or password script")
except pexpect.EOF:
fail(EC_LOGIN_DENIED)
except pexpect.TIMEOUT:
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
sys.exit(result)
if __name__ == "__main__":
main()
diff --git a/fence/agents/xenapi/fence_xenapi.py b/fence/agents/xenapi/fence_xenapi.py
index 8b9857cc..3b6454c5 100644
--- a/fence/agents/xenapi/fence_xenapi.py
+++ b/fence/agents/xenapi/fence_xenapi.py
@@ -1,228 +1,228 @@
-#!/usr/bin/python
+#!/usr/bin/python -tt
#
#############################################################################
# Copyright 2011 Matthew Clark
# This file is part of fence-xenserver
#
# fence-xenserver is free software: you can redistribute it and/or modify
# 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/>.
# Please let me know if you are using this script so that I can work out
# whether I should continue support for it. mattjclark0407 at hotmail dot com
#############################################################################
#############################################################################
# It's only just begun...
# Current status: completely usable. This script is now working well and,
# has a lot of functionality as a result of the fencing.py library and the
# XenAPI libary.
#############################################################################
# Please let me know if you are using this script so that I can work out
# whether I should continue support for it. mattjclark0407 at hotmail dot com
import sys
import atexit
sys.path.append("@FENCEAGENTSLIBDIR@")
from fencing import *
import XenAPI
#BEGIN_VERSION_GENERATION
RELEASE_VERSION=""
REDHAT_COPYRIGHT=""
BUILD_DATE=""
#END_VERSION_GENERATION
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)
# Query the VM for its' associated parameters
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"]):
status = record["power_state"]
if verbose:
print "UUID:", record["uuid"], "NAME:", record["name_label"], "POWER STATUS:", record["power_state"]
# Note that the VM can be in the following states (from the XenAPI document)
# Halted: VM is offline and not using any resources.
# Paused: All resources have been allocated but the VM itself is paused and its vCPUs are not running
# Running: Running
# Paused: VM state has been saved to disk and it is nolonger running. Note that disks remain in-Use while
# 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")
except Exception, exn:
print str(exn)
return "Error"
# 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)
# Query the VM for its' associated parameters
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
session.xenapi.VM.start(vm, False, True)
elif( action == "off" ):
# Force shutdown the VM
session.xenapi.VM.hard_shutdown(vm)
elif( action == "reboot" ):
# Force reboot the VM
session.xenapi.VM.hard_reboot(vm)
except Exception, exn:
print str(exn)
# Function to populate an array of virtual machines and their status
def get_outlet_list(session, options):
result = {}
if options.has_key("--verbose"):
verbose = True
else:
verbose = False
try:
# Return an array of all the VM's on the host
vms = session.xenapi.VM.get_all()
for vm in vms:
# Query the VM for its' associated parameters
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"]):
name = record["name_label"]
uuid = record["uuid"]
status = record["power_state"]
result[uuid] = (name, status)
if verbose:
print "UUID:", record["uuid"], "NAME:", name, "POWER STATUS:", record["power_state"]
except Exception, exn:
print str(exn)
return result
# Function to initiate the XenServer session via the XenAPI library.
def connect_and_login(options):
url = options["--session-url"]
username = options["--username"]
password = options["--password"]
try:
# Create the XML RPC session to the specified URL.
session = XenAPI.Session(url)
# Login using the supplied credentials.
session.xenapi.login_with_password(username, password)
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
# 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)
return session
# return a reference to the VM by either using the UUID or the vm_name/port. If the UUID is set then
# this is tried first as this is the only properly unique identifier.
# Exceptions are not handled in this function, code that calls this must be ready to handle them.
def return_vm_reference(session, options):
if options.has_key("--verbose"):
verbose = True
else:
verbose = False
# Case where the UUID has been specified
if options.has_key("--uuid"):
uuid = options["--uuid"].lower()
# When using the -n parameter for name, we get an error message (in verbose
# mode) that tells us that we didn't find a VM. To immitate that here we
# need to catch and re-raise the exception produced by get_by_uuid.
try:
return session.xenapi.VM.get_by_uuid(uuid)
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"):
vm_name = options["--plug"]
vm_arr = session.xenapi.VM.get_by_name_label(vm_name)
# Need to make sure that we only have one result as the vm_name may
# not be unique. Average case, so do it first.
if len(vm_arr) == 1:
return vm_arr[0]
else:
if len(vm_arr) == 0:
if verbose:
print "No VM's found with a name of \"%s\"" % vm_name
# NAME_INVALID used as the XenAPI throws a UUID_INVALID if it can't find
# a VM with the specified UUID. This should make the output look fairly
# consistent.
raise Exception("NAME_INVALID")
else:
if verbose:
print "Multiple VM's have the name \"%s\", use UUID instead" % vm_name
raise Exception("MULTIPLE_VMS_FOUND")
# We should never get to this case as the input processing checks that either the UUID or
# the name parameter is set. Regardless of whether or not a VM is found the above if
# statements will return to the calling function (either by exception or by a reference
# to the VM).
raise Exception("VM_LOGIC_ERROR")
def main():
device_opt = [ "login", "passwd", "port", "no_login", "no_password", "session_url" ]
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["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."
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)
sys.exit(result)
if __name__ == "__main__":
main()

File Metadata

Mime Type
text/x-diff
Expires
Wed, Feb 26, 11:57 PM (14 h, 50 m ago)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
1465908
Default Alt Text
(209 KB)

Event Timeline