[Cluster-devel] [PATCH 1/3] fencing: new option --method
Add new option method --method for cycle reboot --- fence/agents/lib/fencing.py.py | 80 ++ 1 file changed, 57 insertions(+), 23 deletions(-) diff --git a/fence/agents/lib/fencing.py.py b/fence/agents/lib/fencing.py.py index b4abfb2..59ab91b 100644 --- a/fence/agents/lib/fencing.py.py +++ b/fence/agents/lib/fencing.py.py @@ -25,7 +25,6 @@ EC_STATUS = 8 EC_STATUS_HMC = 9 EC_PASSWORD_MISSING = 10 EC_INVALID_PRIVILEGES = 11 -EC_TOOL_FAIL = 12 TELNET_PATH = /usr/bin/telnet SSH_PATH= /usr/bin/ssh @@ -343,7 +342,16 @@ all_opt = { 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} + 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), + default : onoff, + choices : [ onoff, cycle ], + order : 1} } # options which are added automatically if 'key' is encountered (default is always added) @@ -413,8 +421,7 @@ def fail(error_code): 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., - EC_TOOL_FAIL: Failed: Required tool not found or not accessible. + 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) @@ -782,6 +789,23 @@ def set_multi_power_fn(tn, options, set_power_fn): else: set_power_fn(tn, options) +def multi_reboot_cycle_fn(tn, options, reboot_cycle_fn): + success = False; + 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 = reboot_cycle_fn(tn, options) + if plug_status: + success = plug_status + else: + success = reboot_cycle_fn(tn, options) + return success def show_docs(options, docs = None): device_opt = options[device_opt] @@ -806,7 +830,7 @@ def show_docs(options, docs = None): print __main__.REDHAT_COPYRIGHT sys.exit(0) -def fence_action(tn, options, set_power_fn, get_power_fn, get_outlet_list = None): +def fence_action(tn, options, set_power_fn, get_power_fn, get_outlet_list = None, reboot_cycle_fn = None): result = 0 try: @@ -865,28 +889,38 @@ def fence_action(tn, options, set_power_fn, get_power_fn, get_outlet_list = None else: fail(EC_WAITING_OFF) elif options[--action] == reboot: - 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 - power_on = False - try: + if options.has_key(--method) and options[--method].lower() == cycle: 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: + if multi_reboot_cycle_fn(tn, options, reboot_cycle_fn): power_on = True break - except Exception, ex: - # an error occured during power ON phase in reboot - #
[Cluster-devel] [PATCH 3/3] fence_amt: option --method and new option --amttool-path
Add support for option --method and new option --amttool-path --- fence/agents/amt/fence_amt.py | 72 ++- 1 file changed, 57 insertions(+), 15 deletions(-) diff --git a/fence/agents/amt/fence_amt.py b/fence/agents/amt/fence_amt.py index 8fe2dbc..7077828 100755 --- a/fence/agents/amt/fence_amt.py +++ b/fence/agents/amt/fence_amt.py @@ -1,6 +1,6 @@ #!/usr/bin/python -import sys, subprocess, re +import sys, subprocess, re, os, stat from pipes import quote sys.path.append(@FENCEAGENTSLIBDIR@) from fencing import * @@ -21,12 +21,11 @@ def get_power_status(_, options): try: process = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True) except OSError: -fail(EC_TOOL_FAIL) +fail_usage(Amttool not found or not accessible) process.wait() output = process.communicate() - process.stdout.close() match = re.search('Powerstate:[\\s]*(..)', str(output)) @@ -51,19 +50,44 @@ def set_power_status(_, options): process = subprocess.Popen(cmd, stdout=null, stderr=null, shell=True) except OSError: null.close() -fail(EC_TOOL_FAIL) +fail_usage(Amttool not found or not accessible) process.wait() null.close() return +def reboot_cycle(_, options): +cmd = create_command(options, cycle) + +if options[log] = LOG_MODE_VERBOSE: +options[debug_fh].write(executing: + cmd + \n) + +null = open('/dev/null', 'w') +try: +process = subprocess.Popen(cmd, stdout=null, stderr=null, shell=True) +except OSError: +null.close() +fail_usage(Amttool not found or not accessible) + +status = process.wait() +null.close() + +return not bool(status) + +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 + def create_command(options, action): # --password / -p cmd = AMT_PASSWORD= + quote(options[--password]) -cmd += + options[amttool_path] +cmd += + options[--amttool-path] # --ip / -a cmd += + options[--ip] @@ -77,7 +101,10 @@ def create_command(options, action): elif action == off: cmd = echo \y\| + cmd cmd += powerdown -if action in [on, off] and options.has_key(--boot-options): +elif action == cycle: +cmd = echo \y\| + cmd +cmd += powercycle +if action in [on, off, cycle] and options.has_key(--boot-options): cmd += options[--boot-options] # --use-sudo / -d @@ -86,25 +113,40 @@ def create_command(options, action): return cmd -def main(): - -atexit.register(atexit_handler) - -device_opt = [ ipaddr, no_login, passwd, boot_option, no_port, sudo] - +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), +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 : /usr/bin/amttool, +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)) -options[amttool_path] = /usr/bin/amttool +if not is_executable(options[--amttool-path]): +fail_usage(Amttool not found or not accessible) docs = { } docs[shortdesc] = Fence agent for AMT @@ -112,7 +154,7 @@ def main(): docs[vendorurl] = http://www.intel.com/; show_docs(options, docs) -result = fence_action(None, options, set_power_status, get_power_status, None) +result = fence_action(None, options, set_power_status, get_power_status, None, reboot_cycle) sys.exit(result) -- 1.8.3.1
[Cluster-devel] [PATCH 2/3] fence_ipmilan: option --method and new option --ipmitool-path
Add support for option --method and new option --ipmitool-path --- fence/agents/ipmilan/fence_ipmilan.py | 80 +++ 1 file changed, 54 insertions(+), 26 deletions(-) diff --git a/fence/agents/ipmilan/fence_ipmilan.py b/fence/agents/ipmilan/fence_ipmilan.py index 5c32690..4d33234 100644 --- a/fence/agents/ipmilan/fence_ipmilan.py +++ b/fence/agents/ipmilan/fence_ipmilan.py @@ -11,14 +11,6 @@ REDHAT_COPYRIGHT= BUILD_DATE= #END_VERSION_GENERATION -PATHS = [/usr/local/bull/NSMasterHW/bin/ipmitool, -/usr/bin/ipmitool, -/usr/sbin/ipmitool, -/bin/ipmitool, -/sbin/ipmitool, -/usr/local/bin/ipmitool, -/usr/local/sbin/ipmitool] - def get_power_status(_, options): cmd = create_command(options, status) @@ -28,9 +20,8 @@ def get_power_status(_, options): try: process = subprocess.Popen(shlex.split(cmd), stdout=subprocess.PIPE, stderr=subprocess.PIPE) -except OSError, ex: -print ex -fail(EC_TOOL_FAIL) +except OSError: +fail_usage(Ipmitool not found or not accessible) process.wait() @@ -54,13 +45,31 @@ def set_power_status(_, options): process = subprocess.Popen(shlex.split(cmd), stdout=null, stderr=null) except OSError: null.close() -fail(EC_TOOL_FAIL) +fail_usage(Ipmitool not found or not accessible) process.wait() null.close() return +def reboot_cycle(_, options): +cmd = create_command(options, cycle) + +if options[log] = LOG_MODE_VERBOSE: +options[debug_fh].write(executing: + cmd + \n) + +try: +process = subprocess.Popen(shlex.split(cmd), stdout=subprocess.PIPE, stderr=subprocess.PIPE) +except OSError: +fail_usage(Ipmitool not found or not accessible) + +process.wait() + +out = process.communicate() +process.stdout.close() + +return bool(re.search('chassis power control: cycle', str(out).lower())) + def is_executable(path): if os.path.exists(path): stats = os.stat(path) @@ -68,13 +77,17 @@ def is_executable(path): return True return False -def get_ipmitool_path(): -for path in PATHS: -if is_executable(path): -return path +def get_ipmitool_path(options): +if type(options[--ipmitool-path]) == type(list()): +for path in options[--ipmitool-path]: +if is_executable(path): +return path +else: +if is_executable(options[--ipmitool-path]): +return options[--ipmitool-path] return None -def create_command(options, action): +def create_command(options, action): cmd = options[ipmitool_path] # --lanplus / -L @@ -120,7 +133,7 @@ def define_new_opts(): all_opt[lanplus] = { getopt : L, longopt : lanplus, -help : -L, --lanplusUse Lanplus to improve security of connection, +help : -L, --lanplus Use Lanplus to improve security of connection, required : 0, shortdesc : Use Lanplus to improve security of connection, order: 1 @@ -128,7 +141,7 @@ def define_new_opts(): all_opt[auth] = { getopt : A:, longopt : auth, -help : -A, --auth=[auth]IPMI Lan Auth type (md5|password|none), +help : -A, --auth=[auth] IPMI Lan Auth type (md5|password|none), required : 0, shortdesc : IPMI Lan Auth type., default : none, @@ -138,7 +151,7 @@ def define_new_opts(): all_opt[cipher] = { getopt : C:, longopt : cipher, -help : -C, --cipher=[cipher]Ciphersuite to use (same as ipmitool -C parameter), +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, @@ -147,28 +160,44 @@ def define_new_opts(): all_opt[privlvl] = { getopt : P:, longopt : privlvl, -help : -P, --privlvl=[level]Privilege level on IPMI device (callback|user|operator|administrator), +help : -P, --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 : [/usr/local/bull/NSMasterHW/bin/ipmitool, +/usr/bin/ipmitool, +/usr/sbin/ipmitool, +/bin/ipmitool, +/sbin/ipmitool, +/usr/local/bin/ipmitool, +/usr/local/sbin/ipmitool], +order: 200 +}
Re: [Cluster-devel] [PATCH 2/3] fence_ipmilan: option --method and new option --ipmitool-path
On 11/29/2013 05:32 PM, Ondrej Mular wrote: Add support for option --method and new option --ipmitool-path --- fence/agents/ipmilan/fence_ipmilan.py | 80 +++ 1 file changed, 54 insertions(+), 26 deletions(-) diff --git a/fence/agents/ipmilan/fence_ipmilan.py b/fence/agents/ipmilan/fence_ipmilan.py index 5c32690..4d33234 100644 --- a/fence/agents/ipmilan/fence_ipmilan.py +++ b/fence/agents/ipmilan/fence_ipmilan.py @@ -11,14 +11,6 @@ REDHAT_COPYRIGHT= BUILD_DATE= #END_VERSION_GENERATION -PATHS = [/usr/local/bull/NSMasterHW/bin/ipmitool, -/usr/bin/ipmitool, -/usr/sbin/ipmitool, -/bin/ipmitool, -/sbin/ipmitool, -/usr/local/bin/ipmitool, -/usr/local/sbin/ipmitool] - def get_power_status(_, options): cmd = create_command(options, status) @@ -28,9 +20,8 @@ def get_power_status(_, options): try: process = subprocess.Popen(shlex.split(cmd), stdout=subprocess.PIPE, stderr=subprocess.PIPE) -except OSError, ex: -print ex -fail(EC_TOOL_FAIL) +except OSError: +fail_usage(Ipmitool not found or not accessible) process.wait() @@ -54,13 +45,31 @@ def set_power_status(_, options): process = subprocess.Popen(shlex.split(cmd), stdout=null, stderr=null) except OSError: null.close() -fail(EC_TOOL_FAIL) +fail_usage(Ipmitool not found or not accessible) process.wait() null.close() return +def reboot_cycle(_, options): +cmd = create_command(options, cycle) + +if options[log] = LOG_MODE_VERBOSE: +options[debug_fh].write(executing: + cmd + \n) + +try: +process = subprocess.Popen(shlex.split(cmd), stdout=subprocess.PIPE, stderr=subprocess.PIPE) +except OSError: +fail_usage(Ipmitool not found or not accessible) + +process.wait() + +out = process.communicate() +process.stdout.close() + +return bool(re.search('chassis power control: cycle', str(out).lower())) + def is_executable(path): if os.path.exists(path): stats = os.stat(path) @@ -68,13 +77,17 @@ def is_executable(path): return True return False -def get_ipmitool_path(): -for path in PATHS: -if is_executable(path): -return path +def get_ipmitool_path(options): +if type(options[--ipmitool-path]) == type(list()): +for path in options[--ipmitool-path]: +if is_executable(path): +return path +else: +if is_executable(options[--ipmitool-path]): +return options[--ipmitool-path] return None -def create_command(options, action): +def create_command(options, action): cmd = options[ipmitool_path] # --lanplus / -L @@ -120,7 +133,7 @@ def define_new_opts(): all_opt[lanplus] = { getopt : L, longopt : lanplus, -help : -L, --lanplusUse Lanplus to improve security of connection, +help : -L, --lanplus Use Lanplus to improve security of connection, required : 0, shortdesc : Use Lanplus to improve security of connection, order: 1 @@ -128,7 +141,7 @@ def define_new_opts(): all_opt[auth] = { getopt : A:, longopt : auth, -help : -A, --auth=[auth]IPMI Lan Auth type (md5|password|none), +help : -A, --auth=[auth] IPMI Lan Auth type (md5|password|none), required : 0, shortdesc : IPMI Lan Auth type., default : none, @@ -138,7 +151,7 @@ def define_new_opts(): all_opt[cipher] = { getopt : C:, longopt : cipher, -help : -C, --cipher=[cipher]Ciphersuite to use (same as ipmitool -C parameter), +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, @@ -147,28 +160,44 @@ def define_new_opts(): all_opt[privlvl] = { getopt : P:, longopt : privlvl, -help : -P, --privlvl=[level]Privilege level on IPMI device (callback|user|operator|administrator), +help : -P, --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 : [/usr/local/bull/NSMasterHW/bin/ipmitool, +/usr/bin/ipmitool, +
Re: [Cluster-devel] [PATCH 3/3] fence_amt: option --method and new option --amttool-path
On 11/29/2013 05:32 PM, Ondrej Mular wrote: Add support for option --method and new option --amttool-path --- fence/agents/amt/fence_amt.py | 72 ++- 1 file changed, 57 insertions(+), 15 deletions(-) diff --git a/fence/agents/amt/fence_amt.py b/fence/agents/amt/fence_amt.py index 8fe2dbc..7077828 100755 --- a/fence/agents/amt/fence_amt.py +++ b/fence/agents/amt/fence_amt.py @@ -1,6 +1,6 @@ #!/usr/bin/python -import sys, subprocess, re +import sys, subprocess, re, os, stat from pipes import quote sys.path.append(@FENCEAGENTSLIBDIR@) from fencing import * @@ -21,12 +21,11 @@ def get_power_status(_, options): try: process = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True) except OSError: -fail(EC_TOOL_FAIL) +fail_usage(Amttool not found or not accessible) process.wait() output = process.communicate() - process.stdout.close() match = re.search('Powerstate:[\\s]*(..)', str(output)) @@ -51,19 +50,44 @@ def set_power_status(_, options): process = subprocess.Popen(cmd, stdout=null, stderr=null, shell=True) except OSError: null.close() -fail(EC_TOOL_FAIL) +fail_usage(Amttool not found or not accessible) process.wait() null.close() return +def reboot_cycle(_, options): +cmd = create_command(options, cycle) + +if options[log] = LOG_MODE_VERBOSE: +options[debug_fh].write(executing: + cmd + \n) + +null = open('/dev/null', 'w') +try: +process = subprocess.Popen(cmd, stdout=null, stderr=null, shell=True) +except OSError: +null.close() +fail_usage(Amttool not found or not accessible) + +status = process.wait() +null.close() + +return not bool(status) + +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 + def create_command(options, action): # --password / -p cmd = AMT_PASSWORD= + quote(options[--password]) -cmd += + options[amttool_path] +cmd += + options[--amttool-path] # --ip / -a cmd += + options[--ip] @@ -77,7 +101,10 @@ def create_command(options, action): elif action == off: cmd = echo \y\| + cmd cmd += powerdown -if action in [on, off] and options.has_key(--boot-options): +elif action == cycle: +cmd = echo \y\| + cmd +cmd += powercycle +if action in [on, off, cycle] and options.has_key(--boot-options): cmd += options[--boot-options] # --use-sudo / -d @@ -86,25 +113,40 @@ def create_command(options, action): return cmd -def main(): - -atexit.register(atexit_handler) - -device_opt = [ ipaddr, no_login, passwd, boot_option, no_port, sudo] - +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), +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 : /usr/bin/amttool, similar here. Hardcoding paths is bad. Fabio
Re: [Cluster-devel] [PATCH 2/3] fence_ipmilan: option --method and new option --ipmitool-path
On 11/29/2013 05:32 PM, Ondrej Mular wrote: @@ -147,28 +160,44 @@ def define_new_opts(): all_opt[privlvl] = { getopt : P:, longopt : privlvl, -help : -P, --privlvl=[level]Privilege level on IPMI device (callback|user|operator|administrator), +help : -P, --privlvl=[level] Privilege level on IPMI device (callback|user|operator|administrator), All the reformatting and cosmetic changes should be in a separate commit. Also, this patch assumes that the first patch you posted is applied to the tree. It's not. Sending incremental patches over patches makes it difficult to rebuild the final binary and test it (yes I have ipmi devices at home :)) Fabio