Page MenuHomeClusterLabs Projects

No OneTemporary

diff --git a/configure.ac b/configure.ac
index fdcabfbf..46819991 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1,303 +1,303 @@
# Process this file with autoconf to produce a configure script.
AC_PREREQ([2.63])
AC_INIT([fence-agents],
m4_esyscmd([make/git-version-gen .tarball-version]),
[linux-cluster@redhat.com])
AM_INIT_AUTOMAKE([-Wno-portability dist-bzip2 dist-xz])
LT_PREREQ([2.2.6])
LT_INIT
AC_CONFIG_MACRO_DIR([m4])
AC_CONFIG_SRCDIR([fence/agents/rackswitch/do_rack.h])
AC_CONFIG_HEADERS([make/clusterautoconfig.h])
AC_CANONICAL_HOST
AC_PROG_LIBTOOL
AC_LANG([C])
# Sanitize path
if test "$prefix" = "NONE"; then
prefix="/usr"
if test "$localstatedir" = "\${prefix}/var"; then
localstatedir="/var"
fi
if test "$sysconfdir" = "\${prefix}/etc"; then
sysconfdir="/etc"
fi
if test "$libdir" = "\${exec_prefix}/lib"; then
if test -e /usr/lib64; then
libdir="/usr/lib64"
else
libdir="/usr/lib"
fi
fi
fi
case $exec_prefix in
NONE) exec_prefix=$prefix;;
prefix) exec_prefix=$prefix;;
esac
# Checks for programs.
# check stolen from gnulib/m4/gnu-make.m4
if ! ${MAKE-make} --version /cannot/make/this >/dev/null 2>&1; then
AC_MSG_ERROR([you don't seem to have GNU make; it is required])
fi
AC_PROG_CC
AM_PROG_CC_C_O
AC_PROG_LN_S
AC_PROG_INSTALL
AC_PROG_MAKE_SET
AC_PROG_AWK
AC_PROG_CXX
AC_PROG_RANLIB
## local helper functions
# this function checks if CC support options passed as
# args. Global CFLAGS are ignored during this test.
cc_supports_flag() {
local CFLAGS="$@"
AC_MSG_CHECKING([whether $CC supports "$@"])
AC_COMPILE_IFELSE([int main(){return 0;}] ,
[RC=0; AC_MSG_RESULT([yes])],
[RC=1; AC_MSG_RESULT([no])])
return $RC
}
# this function tests if a library has a certain function
# by using AC_CHECK_LIB but restores the original LIBS global
# envvar. This is required to avoid libtool to link everything
# with everything.
check_lib_no_libs() {
AC_CHECK_LIB([$1], [$2],,
[AC_MSG_ERROR([Unable to find $1 library])])
LIBS=$ac_check_lib_save_LIBS
}
# external libs
PKG_CHECK_MODULES([nss],[nss])
PKG_CHECK_MODULES([nspr],[nspr])
# Checks for header files.
AC_CHECK_HEADERS([arpa/inet.h fcntl.h libintl.h limits.h netdb.h stddef.h sys/socket.h sys/time.h syslog.h])
# Checks for typedefs, structures, and compiler characteristics.
AC_C_INLINE
AC_TYPE_SIZE_T
AC_TYPE_SSIZE_T
AC_TYPE_UINT32_T
# Checks for library functions.
AC_FUNC_FORK
AC_FUNC_MALLOC
AC_CHECK_FUNCS([alarm atexit bzero dup2 memmove memset select socket strcasecmp strchr strdup strerror strtol])
# local options
AC_ARG_ENABLE([debug],
[ --enable-debug enable debug build. ],
[ default="no" ])
AC_ARG_WITH([fenceagentslibdir],
[ --with-fenceagentslibdir=PATH
installation path for fence library. ],
[ FENCEAGENTSLIBDIR="$withval" ],
[ FENCEAGENTSLIBDIR="${datadir}/fence" ])
AC_ARG_WITH([snmpbin],
[ --with-snmpbin=PATH
path to snmp binaries (snmpwalk/get). ],
[ SNMPBIN="$withval" ],
[ SNMPBIN="${bindir}" ])
AC_ARG_WITH([default-config-dir],
[ --with-default-config-dir=DIR
cluster config directory. ],
[ DEFAULT_CONFIG_DIR="$withval" ],
[ DEFAULT_CONFIG_DIR="$sysconfdir/cluster" ])
AC_ARG_WITH([default-config-file],
[ --with-default-config-file=FILE
cluster config file. ],
[ DEFAULT_CONFIG_FILE="$withval" ],
[ DEFAULT_CONFIG_FILE="cluster.conf" ])
AC_ARG_WITH([agents],
[ --with-agents=LIST
list of agents to build/ship (default: all). ],
[ AGENTS_LIST="$withval" ],
[ AGENTS_LIST="all" ])
if test "x$AGENTS_LIST" = x; then
AC_ERROR([No agents selected])
fi
if test "x$AGENTS_LIST" != xall; then
for j in $AGENTS_LIST; do
if ! test -d fence/agents/$j; then
AC_ERROR([Agent $j does not exists])
fi
done
fi
if test "x$AGENTS_LIST" = xall; then
AGENTS_LIST=`find $srcdir/fence/agents -mindepth 2 -maxdepth 2 -name Makefile.am -printf '%h ' | sed -e 's#'$srcdir'/fence/agents/##g' -e 's#lib ##g' -e 's#nss_wrapper ##g'`
fi
XENAPILIB=0
if echo "$AGENTS_LIST" | grep -q xenapi; then
XENAPILIB=1
fi
## random vars
LOGDIR=${localstatedir}/log/cluster
CLUSTERVARRUN=${localstatedir}/run/cluster
CLUSTERDATA=${datadir}/cluster
## path to 3rd-party binaries
AC_PATH_PROG([IPMITOOL_PATH], [ipmitool], [/usr/bin/ipmitool])
AC_PATH_PROG([AMTTOOL_PATH], [amttool], [/usr/bin/amttool])
+AC_PATH_PROG([GNUTLSCLI_PATH], [gnutlscli], [/usr/bin/gnutls-cli])
## do subst
AC_SUBST([DEFAULT_CONFIG_DIR])
AC_DEFINE_UNQUOTED([DEFAULT_CONFIG_DIR], "$(eval echo ${DEFAULT_CONFIG_DIR})",
[Default config directory])
AC_SUBST([DEFAULT_CONFIG_FILE])
AC_DEFINE_UNQUOTED([DEFAULT_CONFIG_FILE], "$(eval echo ${DEFAULT_CONFIG_FILE})",
[Default config file])
AC_SUBST([LOGDIR])
AC_DEFINE_UNQUOTED([LOGDIR], "$(eval echo ${LOGDIR})",
[Default logging directory])
AC_SUBST([CLUSTERVARRUN])
AC_DEFINE_UNQUOTED([CLUSTERVARRUN], "$(eval echo ${CLUSTERVARRUN})",
[Default cluster var/run directory])
AC_SUBST([CLUSTERDATA])
AC_SUBST([FENCEAGENTSLIBDIR])
AC_SUBST([SNMPBIN])
AC_SUBST([AGENTS_LIST])
AM_CONDITIONAL(BUILD_XENAPILIB, test $XENAPILIB -eq 1)
AC_SUBST([IPMITOOL_PATH])
AC_SUBST([AMTTOOL_PATH])
## *FLAGS handling
ENV_CFLAGS="$CFLAGS"
ENV_CPPFLAGS="$CPPFLAGS"
ENV_LDFLAGS="$LDFLAGS"
# debug build stuff
if test "x${enable_debug}" = xyes; then
AC_DEFINE_UNQUOTED([DEBUG], [1], [Compiling Debugging code])
OPT_CFLAGS="-O0"
else
OPT_CFLAGS="-O2"
fi
# gdb flags
if test "x${GCC}" = xyes; then
GDB_FLAGS="-ggdb3"
else
GDB_FLAGS="-g"
fi
# extra warnings
EXTRA_WARNINGS=""
WARNLIST="
all
shadow
missing-prototypes
missing-declarations
strict-prototypes
declaration-after-statement
pointer-arith
write-strings
cast-align
bad-function-cast
missing-format-attribute
format=2
format-security
format-nonliteral
no-long-long
unsigned-char
gnu89-inline
no-strict-aliasing
"
for j in $WARNLIST; do
if cc_supports_flag -W$j; then
EXTRA_WARNINGS="$EXTRA_WARNINGS -W$j";
fi
done
CFLAGS="$ENV_CFLAGS $OPT_CFLAGS $GDB_FLAGS \
$EXTRA_WARNINGS $WERROR_CFLAGS"
CPPFLAGS="-I\$(top_builddir)/make -I\$(top_srcdir)/make -I. $ENV_CPPFLAGS"
LDFLAGS="$ENV_LDFLAGS"
AC_CONFIG_FILES([Makefile
fence/Makefile
fence/agents/Makefile
fence/agents/alom/Makefile
fence/agents/apc/Makefile
fence/agents/apc_snmp/Makefile
fence/agents/baytech/Makefile
fence/agents/bladecenter/Makefile
fence/agents/brocade/Makefile
fence/agents/bullpap/Makefile
fence/agents/cisco_mds/Makefile
fence/agents/cisco_ucs/Makefile
fence/agents/cpint/Makefile
fence/agents/drac/Makefile
fence/agents/drac5/Makefile
fence/agents/dummy/Makefile
fence/agents/eaton_snmp/Makefile
fence/agents/egenera/Makefile
fence/agents/eps/Makefile
fence/agents/hpblade/Makefile
fence/agents/ibmblade/Makefile
fence/agents/ipdu/Makefile
fence/agents/ifmib/Makefile
fence/agents/ilo/Makefile
fence/agents/ilo_mp/Makefile
fence/agents/intelmodular/Makefile
fence/agents/ipmilan/Makefile
fence/agents/kdump/Makefile
fence/agents/ldom/Makefile
fence/agents/lib/Makefile
fence/agents/lpar/Makefile
fence/agents/manual/Makefile
fence/agents/mcdata/Makefile
- fence/agents/nss_wrapper/Makefile
fence/agents/rackswitch/Makefile
fence/agents/rhevm/Makefile
fence/agents/rsa/Makefile
fence/agents/rsb/Makefile
fence/agents/sanbox2/Makefile
fence/agents/scsi/Makefile
fence/agents/virsh/Makefile
fence/agents/vixel/Makefile
fence/agents/vmware/Makefile
fence/agents/vmware_soap/Makefile
fence/agents/wti/Makefile
fence/agents/xcat/Makefile
fence/agents/xenapi/Makefile
fence/agents/hds_cb/Makefile
fence/agents/zvm/Makefile
doc/Makefile])
AC_OUTPUT
diff --git a/fence/agents/Makefile.am b/fence/agents/Makefile.am
index f14d27f4..c47f5d5d 100644
--- a/fence/agents/Makefile.am
+++ b/fence/agents/Makefile.am
@@ -1,5 +1,4 @@
MAINTAINERCLEANFILES = Makefile.in
SUBDIRS = lib \
- nss_wrapper \
$(AGENTS_LIST)
diff --git a/fence/agents/lib/fencing.py.py b/fence/agents/lib/fencing.py.py
index 74a196a8..9ef54cb2 100644
--- a/fence/agents/lib/fencing.py.py
+++ b/fence/agents/lib/fencing.py.py
@@ -1,1136 +1,1135 @@
#!/usr/bin/python
import sys, getopt, time, os, uuid, pycurl, stat
import pexpect, re, atexit, syslog
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
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 = "@LIBEXECDIR@/fence_nss_wrapper"
+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 },
"quiet" : {
"getopt" : "q",
"help" : "",
"order" : 50 },
"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 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 },
"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 },
"module_name" : {
"getopt" : "m:",
"longopt" : "module-name",
"help" : "-m, --module-name=<module> DRAC/MC module name",
"required" : "0",
"shortdesc" : "DRAC/MC module name",
"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 },
"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 },
"test" : {
"getopt" : "T",
"help" : "",
"order" : 1,
"obsolete" : "use -o status instead" },
"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 },
"udpport" : {
"getopt" : "u:",
"longopt" : "udpport",
"help" : "-u, --udpport UDP/TCP port to use",
"required" : "0",
"shortdesc" : "UDP/TCP port to use for connection with device",
"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},
"uuid" : {
"getopt" : "U:",
"longopt" : "uuid",
"help" : "-U, --uuid UUID of the VM to fence",
"required" : "0",
"shortdesc" : "The UUID of the virtual machine to fence.",
"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", "quiet", "version", "action", "agent", \
"power_timeout", "shell_timeout", "login_timeout", "power_wait", "retry_on", "delay" ],
"passwd" : [ "passwd_script" ],
"secure" : [ "identity_file", "ssh_options" ],
"ipaddr" : [ "inet4_only", "inet6_only" ],
"port" : [ "separator" ],
"module_name" : [ "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):
pexpect.spawn.__init__(self, command)
self.opt = options
def log_expect(self, options, pattern, timeout):
result = self.expect(pattern, timeout)
if options["log"] >= LOG_MODE_VERBOSE:
options["debug_fh"].write(self.before + self.after)
return result
# 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:
sys.stderr.write("%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 version(command, release, build_date, copyright_notice):
print command, " ", release, " ", build_date
if len(copyright_notice) > 0:
print copyright_notice
def fail_usage(message = ""):
if len(message) > 0:
sys.stderr.write(message+"\n")
sys.stderr.write("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"
sys.stderr.write(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, _value 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("^(.*--\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"])
## Compatibility layer
if avail_opt.count("module_name") == 1:
getopt_string += "n:"
longopt_list.append("plug=")
##
## Read options from command line or standard input
#####
if len(sys.argv) > 1:
try:
opt, _args = getopt.gnu_getopt(sys.argv[1:], getopt_string, longopt_list)
except getopt.GetoptError, error:
fail_usage("Parse error: " + error.msg)
## Transform short getopt to long one which are used in fencing agents
#####
old_opt = opt
opt = { }
for o in dict(old_opt).keys():
if o.startswith("--"):
for x in all_opt.keys():
if all_opt[x].has_key("longopt") and "--" + all_opt[x]["longopt"] == o:
opt["--" + all_opt[x]["longopt"]] = dict(old_opt)[o]
else:
for x in all_opt.keys():
if all_opt[x].has_key("getopt") and all_opt[x].has_key("longopt") and \
("-" + all_opt[x]["getopt"] == o or "-" + all_opt[x]["getopt"].rstrip(":") == o):
opt["--" + all_opt[x]["longopt"]] = dict(old_opt)[o]
opt[o] = dict(old_opt)[o]
## Compatibility Layer
#####
z = dict(opt)
if z.has_key("-T") == 1:
z["--action"] = "status"
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]
## Compatibility Layer
######
if name == "blade":
name = "port"
elif name == "option":
name = "action"
elif name == "fm":
name = "port"
elif name == "hostname":
name = "ipaddr"
elif name == "modulename":
name = "module_name"
elif name == "port" and 1 == avail_opt.count("drac_version"):
name = "module_name"
##
######
if avail_opt.count(name) == 0:
sys.stderr.write("Parse error: Ignoring unknown option '"+line+"'\n")
syslog.syslog(syslog.LOG_WARNING, "Parse error: Ignoring unknown option '"+line)
continue
if all_opt[name]["getopt"].endswith(":"):
opt["--"+all_opt[name]["longopt"].rstrip(":")] = value
elif value.lower() in [ "1", "yes", "on", "true" ]:
opt["--"+all_opt[name]["longopt"]] = "1"
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"):
options["log"] = LOG_MODE_VERBOSE
else:
options["log"] = LOG_MODE_QUIET
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"
# UUID is now only alias for --plug; because we can detect it automatically
if options.has_key("--uuid"):
options["--plug"] == options["--uuid"]
del options["--uuid"]
## 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"):
fail_usage("Failed: You have to enter plug number")
if options.has_key("--password-script"):
options["--password"] = os.popen(options["--password-script"]).read().rstrip()
if options.has_key("--debug-file"):
try:
options["debug_fh"] = file (options["--debug-file"], "w")
except IOError:
fail_usage("Failed: Unable to create file " + options["--debug-file"])
if options.has_key("debug_fh") == 0:
options["debug_fh"] = sys.stderr
if options.has_key("--snmp-priv-passwd-script"):
options["--snmp-priv-passwd"] = os.popen(options["--snmp-priv-passwd-script"]).read().rstrip()
if options.has_key("--ipport") == False:
if options.has_key("--ssh"):
options["--ipport"] = 22
elif options.has_key("--ssl"):
options["--ipport"] = 443
elif device_opt.count("web"):
options["--ipport"] = 80
else:
options["--ipport"] = 23
if options.has_key("--plug") and len(options["--plug"].split(",")) > 1 and options.has_key("--method") and options["--method"] == "cycle":
fail_usage("Failed: Cannot use --method cycle for more than 1 plug")
for opt in device_opt:
if all_opt[opt].has_key("choices"):
long = "--" + all_opt[opt]["longopt"]
possible_values_upper = map (lambda y : y.upper(), all_opt[opt]["choices"])
if options.has_key(long):
options[long] = options[long].upper()
if not options["--" + all_opt[opt]["longopt"]] in possible_values_upper:
fail_usage("Failed: You have to enter a valid choice for %s from the valid values: %s" % ("--" + all_opt[opt]["longopt"] , str(all_opt[opt]["choices"])))
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") and 0 == options["device_opt"].count("partition") and \
0 == options["device_opt"].count("module_name"):
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
sys.stderr.write(str(ex))
syslog.syslog(syslog.LOG_NOTICE, str(ex))
pass
if power_on == False:
# this should not fail as node was fenced succesfully
sys.stderr.write('Timed out waiting to power ON\n')
syslog.syslog(syslog.LOG_NOTICE, "Timed out waiting to power ON")
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:
sys.stderr.write(ex[1] + "\n")
syslog.syslog(syslog.LOG_ERR, ex[1])
fail(EC_TIMED_OUT)
return result
def fence_login(options, re_login_string = "(login\s*: )|(Login Name: )|(username: )|(User Name :)"):
force_ipvx=""
if (options.has_key("--inet6-only")):
force_ipvx = "-6 "
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"]:
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"):
- command = '%s %s %s %s' % (SSL_PATH, force_ipvx, options["--ip"], options["--ipport"])
+ command = '%s --insecure --crlf -p %s %s' % (SSL_PATH, options["--ipport"], options["--ip"])
try:
conn = fspawn(options, command)
except pexpect.ExceptionPexpect, ex:
- ## SSL telnet is part of the fencing package
sys.stderr.write(str(ex) + "\n")
syslog.syslog(syslog.LOG_ERR, str(ex))
sys.exit(EC_GENERIC_ERROR)
elif options.has_key("--ssh") and 0 == options.has_key("--identity-file"):
command = '%s %s %s@%s -p %s -o PubkeyAuthentication=no' % (SSH_PATH, force_ipvx, options["--username"], options["--ip"], options["--ipport"])
if options.has_key("--ssh-options"):
command += ' ' + options["--ssh-options"]
try:
conn = fspawn(options, command)
except pexpect.ExceptionPexpect, ex:
sys.stderr.write(str(ex) + "\n")
syslog.syslog(syslog.LOG_ERR, str(ex))
sys.stderr.write("Due to limitations, binary dependencies on fence agents "
"are not in the spec file and must be installed separately." + "\n")
sys.exit(EC_GENERIC_ERROR)
if options.has_key("telnet_over_ssh"):
#This is for stupid ssh servers (like ALOM) which behave more like telnet (ignore name and display login prompt)
result = conn.log_expect(options, [ re_login, "Are you sure you want to continue connecting (yes/no)?" ], int(options["--login-timeout"]))
if result == 1:
conn.sendline("yes") # Host identity confirm
conn.log_expect(options, re_login, int(options["--login-timeout"]))
conn.sendline(options["--username"])
conn.log_expect(options, re_pass, int(options["--login-timeout"]))
else:
result = conn.log_expect(options, [ "ssword:", "Are you sure you want to continue connecting (yes/no)?" ], int(options["--login-timeout"]))
if result == 1:
conn.sendline("yes")
conn.log_expect(options, "ssword:", int(options["--login-timeout"]))
conn.sendline(options["--password"])
conn.log_expect(options, options["--command-prompt"], int(options["--login-timeout"]))
elif options.has_key("--ssh") and options.has_key("--identity-file"):
command = '%s %s %s@%s -i %s -p %s' % (SSH_PATH, force_ipvx, options["--username"], options["--ip"], options["--identity-file"], options["--ipport"])
if options.has_key("--ssh-options"):
command += ' ' + options["--ssh-options"]
try:
conn = fspawn(options, command)
except pexpect.ExceptionPexpect, ex:
sys.stderr.write(str(ex) + "\n")
syslog.syslog(syslog.LOG_ERR, str(ex))
sys.stderr.write("Due to limitations, binary dependencies on fence agents "
"are not in the spec file and must be installed separately." + "\n")
sys.exit(EC_GENERIC_ERROR)
result = conn.log_expect(options, [ options["--command-prompt"], \
"Are you sure you want to continue connecting (yes/no)?", \
"Enter passphrase for key '" + options["--identity-file"] + "':" ], int(options["--login-timeout"]))
if result == 1:
conn.sendline("yes")
conn.log_expect(options, [ options["--command-prompt"], "Enter passphrase for key '"+options["--identity-file"]+"':"] , int(options["--login-timeout"]))
if result != 0:
if options.has_key("--password"):
conn.sendline(options["--password"])
conn.log_expect(options, options["--command-prompt"], int(options["--login-timeout"]))
else:
fail_usage("Failed: You have to enter passphrase (-p) for identity file")
else:
try:
conn = fspawn(options, TELNET_PATH)
conn.send("set binary\n")
conn.send("open %s -%s\n"%(options["--ip"], options["--ipport"]))
except pexpect.ExceptionPexpect, ex:
sys.stderr.write(str(ex) + "\n")
syslog.syslog(syslog.LOG_ERR, str(ex))
sys.stderr.write("Due to limitations, binary dependencies on fence agents "
"are not in the spec file and must be installed separately." + "\n")
sys.exit(EC_GENERIC_ERROR)
result = conn.log_expect(options, re_login, int(options["--login-timeout"]))
conn.send_eol(options["--username"])
## automatically change end of line separator
screen = conn.read_nonblocking(size=100, timeout=int(options["--shell-timeout"]))
if (re_login.search(screen) != None):
options["eol"] = "\n"
conn.send_eol(options["--username"])
result = conn.log_expect(options, re_pass, int(options["--login-timeout"]))
elif (re_pass.search(screen) == None):
conn.log_expect(options, re_pass, int(options["--shell-timeout"]))
try:
conn.send_eol(options["--password"])
valid_password = conn.log_expect(options, [ re_login ] + options["--command-prompt"], int(options["--shell-timeout"]))
if valid_password == 0:
## password is invalid or we have to change EOL separator
options["eol"] = "\r"
conn.send_eol("")
screen = conn.read_nonblocking(size=100, timeout=int(options["--shell-timeout"]))
## after sending EOL the fence device can either show 'Login' or 'Password'
if (re_login.search(screen) != None):
conn.send_eol("")
conn.send_eol(options["--username"])
conn.log_expect(options, re_pass, int(options["--login-timeout"]))
conn.send_eol(options["--password"])
conn.log_expect(options, options["--command-prompt"], int(options["--login-timeout"]))
except KeyError:
fail(EC_PASSWORD_MISSING)
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/nss_wrapper/Makefile.am b/fence/agents/nss_wrapper/Makefile.am
deleted file mode 100644
index 16273ed5..00000000
--- a/fence/agents/nss_wrapper/Makefile.am
+++ /dev/null
@@ -1,7 +0,0 @@
-MAINTAINERCLEANFILES = Makefile.in
-
-libexec_PROGRAMS = fence_nss_wrapper
-
-fence_nss_wrapper_CFLAGS = $(nss_CFLAGS) $(nspr_CFLAGS)
-
-fence_nss_wrapper_LDFLAGS = $(nss_LIBS) $(nspr_LIBS)
diff --git a/fence/agents/nss_wrapper/fence_nss_wrapper.c b/fence/agents/nss_wrapper/fence_nss_wrapper.c
deleted file mode 100644
index b960cf03..00000000
--- a/fence/agents/nss_wrapper/fence_nss_wrapper.c
+++ /dev/null
@@ -1,484 +0,0 @@
-/** @file fence_nss_wrapper.c - Main source code of hobbit like tool with
- support for NSS (SSL) connection.
-*/
-#include "clusterautoconfig.h"
-
-#include <stdio.h>
-#include <nss.h>
-#include <ssl.h>
-#include <prio.h>
-#include <prnetdb.h>
-#include <prerror.h>
-#include <prinit.h>
-#include <getopt.h>
-#include <libgen.h>
-
-/*---- CONSTANTS -------------*/
-
-/** Default operation = connect and telnet*/
-#define OPERATION_DEFAULT 0
-/** Operation display help*/
-#define OPERATION_HELP 1
-
-/** Default mode of connection. Try first found working address*/
-#define MODE_DEFAULT 3
-/** Use only IPv4*/
-#define MODE_IP4MODE 1
-/** Use only IPv6*/
-#define MODE_IP6MODE 2
-/** Use RAW mode - no change of \r and \n to \r\n*/
-#define MODE_RAW 4
-/** Use non-secure mode (without SSL, only pure socket)*/
-#define MODE_NO_SSL 8
-
-/*------ Functions ---------------*/
-
-/** Return port inserted in string. Fuction tests, if port is integer, and than return
- integer value of string. Otherwise, it will use /etc/services. On fail, it returns
- port -1.
- @param port_s Input port or service name
- @return port number (converted with ntohs) on success, otherwise -1.
-*/
-static int return_port(char *port_s) {
- char *end_c;
- int res;
- struct servent *serv;
-
- res=strtol(port_s,&end_c,10);
-
- if (*end_c=='\0') return res;
-
- /*It's not number, so try service name*/
- serv=getservbyname(port_s,NULL);
-
- if (serv==NULL) return -1;
-
- return ntohs(serv->s_port);
-}
-
-/** Hook handler for bad certificate (because we have no DB, EVERY certificate is bad).
- Returned value is always SECSuccess = it's ok certificate.
- @param arg NULL value
- @param fd socket cased error
- @return SECSuccess.
-*/
-static SECStatus nss_bad_cert_hook(void *arg,PRFileDesc *fd) {
- return SECSuccess;
-}
-
-/** Display last NSPR/NSS error code and user readable message.
-*/
-static void print_nspr_error(void) {
- fprintf(stderr,"Error (%d): %s\n",PR_GetError(),PR_ErrorToString(PR_GetError(),PR_LANGUAGE_I_DEFAULT));
-}
-
-/** Initialize NSS. NSS is initialized without DB and with
- domnestic policy.
- @return 1 on success, otherwise 0.
-*/
-static int init_nss(void) {
- if ((NSS_NoDB_Init(NULL)!=SECSuccess) ||
- (NSS_SetDomesticPolicy()!=SECSuccess)) {
- print_nspr_error();
-
- return 0;
- }
-
- SSL_ClearSessionCache();
-
- return 1;
-}
-
-/** Create socket. If ssl is >0, socket is ssl enabled.
- @param ssl Enable ssl (Client, SSL2+3, no TLS, compatible hello) if PR_TRUE, otherwise no.
- @param ipv6 New socket will be IPv4 if this value is 0, otherwise it will be ipv6
- @return NULL on error, otherwise socket.
-*/
-static PRFileDesc *create_socket(int ssl,int ipv6) {
- PRFileDesc *res_socket;
-
- res_socket=PR_OpenTCPSocket((ipv6?PR_AF_INET6:PR_AF_INET));
- if (res_socket==NULL) {
- print_nspr_error();
-
- return NULL;
- }
-
- if (!ssl) return res_socket;
-
- if (!(res_socket=SSL_ImportFD(NULL,res_socket))) {
- print_nspr_error();
-
- return NULL;
- }
-
- if ((SSL_OptionSet(res_socket,SSL_SECURITY,ssl)!=SECSuccess) ||
- (SSL_OptionSet(res_socket,SSL_HANDSHAKE_AS_SERVER,PR_FALSE)!=SECSuccess) ||
- (SSL_OptionSet(res_socket,SSL_HANDSHAKE_AS_CLIENT,PR_TRUE)!=SECSuccess) ||
- (SSL_OptionSet(res_socket,SSL_ENABLE_SSL2,ssl)!=SECSuccess) ||
- (SSL_OptionSet(res_socket,SSL_ENABLE_SSL3,ssl)!=SECSuccess) ||
- (SSL_OptionSet(res_socket,SSL_ENABLE_TLS,PR_FALSE)!=SECSuccess) ||
- (SSL_OptionSet(res_socket,SSL_V2_COMPATIBLE_HELLO,ssl)!=SECSuccess) ||
- (SSL_SetPKCS11PinArg(res_socket,NULL)==-1) ||
- (SSL_AuthCertificateHook(res_socket,SSL_AuthCertificate,CERT_GetDefaultCertDB())!=SECSuccess) ||
- (SSL_BadCertHook(res_socket,nss_bad_cert_hook,NULL)!=SECSuccess)) {
- print_nspr_error();
-
- if (PR_Close(res_socket)!=PR_SUCCESS) {
- print_nspr_error();
- }
-
- return NULL;
- }
-
- return res_socket;
-}
-
-/** Create socket and connect to it.
- @param hostname Hostname to connect
- @param port Port name/number to connect
- @param mode Connection mode. Bit-array of MODE_NO_SSL, MODE_IP6MODE, MODE_IP4MODE.
- @return NULL on error, otherwise connected socket.
-*/
-static PRFileDesc *create_connected_socket(char *hostname,int port,int mode) {
- PRAddrInfo *addr_info;
- void *addr_iter;
- PRNetAddr addr;
- PRFileDesc *localsocket;
- int can_exit,valid_socket;
- PRUint16 af_spec;
-
- localsocket=NULL;
-
- addr_info=NULL;
-
- af_spec=PR_AF_UNSPEC;
-
- if (!(mode&MODE_IP6MODE)) af_spec=PR_AF_INET;
-
- addr_info=PR_GetAddrInfoByName(hostname,af_spec,PR_AI_ADDRCONFIG);
-
- if (addr_info == NULL) {
- print_nspr_error();
- return NULL;
- }
-
- /*We have socket -> enumerate and try to connect*/
- addr_iter=NULL;
- can_exit=0;
- valid_socket=0;
-
- while (!can_exit) {
- addr_iter=PR_EnumerateAddrInfo(addr_iter,addr_info,port,&addr);
-
- if (addr_iter==NULL) {
- can_exit=1;
- } else {
- if ((PR_NetAddrFamily(&addr)==PR_AF_INET && (mode&MODE_IP4MODE)) ||
- (PR_NetAddrFamily(&addr)==PR_AF_INET6 && (mode&MODE_IP6MODE))) {
- /*Type of address is what user want, try to create socket and make connection*/
-
- /*Create socket*/
- localsocket=create_socket(!(mode&MODE_NO_SSL),(PR_NetAddrFamily(&addr)==PR_AF_INET6));
-
- if (localsocket) {
- /*Try to connect*/
- if (PR_Connect(localsocket,&addr,PR_INTERVAL_NO_TIMEOUT)==PR_SUCCESS) {
- /*Force handshake*/
- if ((!(mode&MODE_NO_SSL)) && SSL_ForceHandshake(localsocket)!=SECSuccess) {
- /*Handhake failure -> fail*/
- print_nspr_error();
- if (PR_Close(localsocket)!=PR_SUCCESS) {
- print_nspr_error();
- can_exit=1;
- }
- localsocket=NULL;
- }
-
- /*Socket is connected -> we can return it*/
- can_exit=1;
- } else {
- /*Try another address*/
- if (PR_Close(localsocket)!=PR_SUCCESS) {
- print_nspr_error();
- can_exit=1;
- }
- localsocket=NULL;
- }
- }
- }
- }
- }
-
- if (!localsocket) {
- /*Socket is unvalid -> we don't found any usable address*/
- fprintf(stderr,"Can't connect to host %s on port %d!\n",hostname,port);
- }
-
- PR_FreeAddrInfo(addr_info);
-
- return localsocket;
-}
-
-/** Parse arguments from command line.
- @param argc Number of arguments in argv
- @param argv Array of arguments
- @param mode Pointer to int will be filled with OPERATION_DEFAULT or OPERATION_HELP.
- @param mode Pointer to int will be filled with MODE_DEFAULT, MODE_IP4MODE or MODE_IP4MODE.
- @return 1 on success, otherwise 0.
-*/
-static int parse_cli(int argc,char *argv[],int *operation,int *mode,char **hostname,char **port) {
- int opt;
-
- *operation=OPERATION_DEFAULT;
- *mode=MODE_DEFAULT;
- *port=NULL;
- *hostname=NULL;
-
- while ((opt=getopt(argc,argv,"h46rz"))!=-1) {
- switch (opt) {
- case 'h':
- *operation=OPERATION_HELP;
-
- return 0;
- break;
-
- case '4':
- (*mode)&=~MODE_IP6MODE;
- (*mode)|=MODE_IP4MODE;
- break;
-
- case '6':
- (*mode)&=~MODE_IP4MODE;
- (*mode)|=MODE_IP6MODE;
- break;
-
- case 'r':
- (*mode)|=MODE_RAW;
- break;
-
- case 'z':
- (*mode)|=MODE_NO_SSL;
- break;
-
- default:
- return 0;
- break;
- }
- }
-
- if (argc-optind<2) {
- fprintf(stderr,"Hostname and port is expected!\n");
-
- return 0;
- }
-
- *hostname=argv[optind];
- *port=argv[optind+1];
-
- return 1;
-}
-
-/** Show usage of application.
- @param pname Name of program (usually basename of argv[0])
-*/
-static void show_usage(char *pname) {
- printf("usage: %s [options] hostname port\n", pname);
- printf(" -4 Force to use IPv4\n");
- printf(" -6 Force to use IPv6\n");
- printf(" -r Use RAW connection (don't convert \\r and \\n characters)\n");
- printf(" -z Don't use SSL connection (use pure socket)\n");
- printf(" -h Show this help\n");
-}
-
-/** Convert End Of Lines (Unix \n, Macs \r or DOS/Win \r\n) to \r\n.
- @param in_buffer Input buffer
- @param in_size Input buffer size
- @param out_buffer Output buffer (must be prealocated). Should be (2*in_size) (in worst case)
- @param out_size There will be size of out_buffer
- @param in_state Internal state of finite automata. First call should have this 0, other calls
- shouldn't change this value. After end of file, you may add to this value +100 and call this
- again, to make sure of proper end (in_buffer can be in this case everything, including NULL).
-*/
-static void convert_eols(char *in_buffer,int in_size,char *out_buffer,int *out_size,int *in_state) {
- int in_pos,out_pos;
- int status;
- char in_char;
-
- out_pos=0;
- status=*in_state;
-
- if (status==100 || status==101) {
- if (status==101) {
- out_buffer[out_pos++]='\r';
- out_buffer[out_pos++]='\n';
- }
- } else {
- for (in_pos=0;in_pos<in_size;in_pos++) {
- in_char=in_buffer[in_pos];
-
- switch (status) {
- case 0:
- if (in_char=='\r') status=1;
- if (in_char=='\n') {
- out_buffer[out_pos++]='\r';
- out_buffer[out_pos++]='\n';
- }
- if ((in_char!='\r') && (in_char!='\n')) out_buffer[out_pos++]=in_char;
- break;
-
- case 1:
- out_buffer[out_pos++]='\r';
- out_buffer[out_pos++]='\n';
-
- if (in_char!='\n') out_buffer[out_pos++]=in_char;
-
- status=0;
- break;
- }
- }
- }
-
- *out_size=out_pos;
- *in_state=status;
-}
-
-/** Start polling cycle.
- @param socket Network connected socket.
- @param mode Bit-array of MODE_*. This function take care on MODE_RAW.
- @return 0 on failure, otherwise 1
-*/
-static int poll_cycle(PRFileDesc *localsocket,int mode) {
- PRPollDesc pool[2];
- char buffer[1024],buffer_eol[1024*2];
- int readed_bytes;
- int can_exit;
- int res;
- int bytes_to_write;
- int eol_state;
-
- can_exit=0;
- eol_state=0;
-
- /* Fill pool*/
- pool[1].fd=localsocket;
- pool[0].fd=PR_STDIN;
- pool[0].in_flags=pool[1].in_flags=PR_POLL_READ;
- pool[0].out_flags=pool[1].out_flags=0;
-
- while (!can_exit) {
- res=(PR_Poll(pool,sizeof(pool)/sizeof(PRPollDesc),PR_INTERVAL_NO_TIMEOUT));
-
- if (res==-1) {
- print_nspr_error();
-
- return 0;
- }
-
- if (pool[1].out_flags&PR_POLL_READ) {
- /*We have something in socket*/
- if ((readed_bytes=PR_Read(pool[1].fd,buffer,sizeof(buffer)))>0) {
- if (PR_Write(PR_STDOUT,buffer,readed_bytes)!=readed_bytes) {
- print_nspr_error();
-
- return 0;
- }
- } else {
- /*End of stream -> quit*/
- can_exit=1;
- }
- }
-
- if (pool[0].out_flags&(PR_POLL_READ|PR_POLL_HUP)) {
- /*We have something in stdin*/
- if ((readed_bytes=PR_Read(pool[0].fd,buffer,sizeof(buffer)))>0) {
-
- if (!(mode&MODE_RAW)) {
- convert_eols(buffer,readed_bytes,buffer_eol,&bytes_to_write,&eol_state);
- } else
- bytes_to_write=readed_bytes;
-
- if (PR_Write(pool[1].fd,(mode&MODE_RAW?buffer:buffer_eol),bytes_to_write)!=bytes_to_write) {
- print_nspr_error();
-
- return 0;
- }
- } else {
- /*End of stream -> send EOL (if needed)*/
- if (!(mode&MODE_RAW)) {
- eol_state+=100;
- convert_eols(NULL,0,buffer_eol,&bytes_to_write,&eol_state);
- if (PR_Write(pool[1].fd,buffer_eol,bytes_to_write)!=bytes_to_write) {
- print_nspr_error();
-
- return 0;
- }
- }
- }
- }
-
- pool[0].out_flags=pool[1].out_flags=0;
- } /*while (!can_exit)*/
-
- return 1;
-}
-
-static void atexit_handler(void) {
- if (PR_Initialized())
- PR_Cleanup();
-
- if (fclose(stdout)!=0) {
- fprintf(stderr,"Can't close stdout!\n");
-
- exit(1);
- }
-}
-
-/** Entry point of application.
- @param argc Number of arguments on command line
- @param argv Array of strings with arguments from command line
- @return 0 on success, otherwise >0.
-*/
-int main(int argc,char *argv[]) {
- int mode,operation;
- char *hostname, *port;
- char *pname;
- int port_n;
- PRFileDesc *fd_socket;
- int res;
-
- pname=basename(argv[0]);
-
- atexit(atexit_handler);
-
- if (!parse_cli(argc,argv,&operation,&mode,&hostname,&port) || operation==OPERATION_HELP) {
- show_usage(pname);
-
- if (operation!=OPERATION_HELP) return 1;
-
- return 0;
- }
-
- if ((port_n=return_port(port))==-1) {
- fprintf(stderr,"Error. Unknown port number/name %s!\n",port);
-
- return 1;
- }
-
- if (!(mode&MODE_NO_SSL)) {
- if (!init_nss()) return 1;
- }
-
- if (!(fd_socket=create_connected_socket(hostname,port_n,mode)))
- return 1;
-
- res=poll_cycle(fd_socket,mode);
-
- if (PR_Close(fd_socket)!=PR_SUCCESS) {
- print_nspr_error();
-
- return 1;
- }
-
- return (res?0:1);
-}
diff --git a/make/fencebuild.mk b/make/fencebuild.mk
index 14e33b7c..819ac365 100644
--- a/make/fencebuild.mk
+++ b/make/fencebuild.mk
@@ -1,18 +1,19 @@
$(TARGET): $(SRC)
bash $(top_srcdir)/scripts/fenceparse \
$(top_srcdir)/make/copyright.cf REDHAT_COPYRIGHT \
$(VERSION) \
$(abs_srcdir) $@ | \
sed \
-e 's#@''FENCEAGENTSLIBDIR@#${FENCEAGENTSLIBDIR}#g' \
-e 's#@''SNMPBIN@#${SNMPBIN}#g' \
-e 's#@''LOGDIR@#${LOGDIR}#g' \
-e 's#@''SBINDIR@#${sbindir}#g' \
-e 's#@''LIBEXECDIR@#${libexecdir}#g' \
-e 's#@''IPMITOOL_PATH@#${IPMITOOL_PATH}#g' \
-e 's#@''AMTTOOL_PATH@#${AMTTOOL_PATH}#g' \
+ -e 's#@''GNUTLSCLI_PATH@#${GNUTLSCLI_PATH}#g' \
> $@
if [ 0 -eq `echo "$(SRC)" | grep fence_ &> /dev/null; echo $$?` ]; then \
PYTHONPATH=$(abs_srcdir)/../lib:$(abs_builddir)/../lib $(top_srcdir)/fence/agents/lib/check_used_options.py $@; \
else true ; fi

File Metadata

Mime Type
text/x-diff
Expires
Sat, Jan 25, 11:07 AM (1 d, 7 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
1322270
Default Alt Text
(62 KB)

Event Timeline