[Cluster-devel] [PATCH 1/2] fence_ipmilan: port fencing agent to fencing library

Fabio M. Di Nitto fdinitto at redhat.com
Thu Nov 21 15:48:34 UTC 2013


Hi Ondrej,

On 11/21/2013 4:16 PM, Ondrej Mular wrote:
> This is port of fence_ipmilan to fencing library. Also added fail message to fencing library if tool (e.g. impitool, amttool...) is not accessible.
> 
> ---
>  fence/agents/ipmilan/fence_ipmilan.py | 184 ++++++++++++++++++++++++++++++++++
>  fence/agents/lib/fencing.py.py        |   4 +-
>  2 files changed, 187 insertions(+), 1 deletion(-)
>  create mode 100644 fence/agents/ipmilan/fence_ipmilan.py
> 
> diff --git a/fence/agents/ipmilan/fence_ipmilan.py b/fence/agents/ipmilan/fence_ipmilan.py
> new file mode 100644
> index 0000000..5c32690
> --- /dev/null
> +++ b/fence/agents/ipmilan/fence_ipmilan.py
> @@ -0,0 +1,184 @@
> +#!/usr/bin/python
> +
> +import sys, shlex, stat, subprocess, re, os
> +from pipes import quote
> +sys.path.append("@FENCEAGENTSLIBDIR@")
> +from fencing import *
> +
> +#BEGIN_VERSION_GENERATION
> +RELEASE_VERSION=""
> +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"]

this hard-cording it bad.

Always use OS define PATH and if really necessary allow user to override
with an option (for example: --pathtoipmitool=/usr/local....)

Fabio

> +
> +def get_power_status(_, options):
> +
> +    cmd = create_command(options, "status")
> +
> +    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, ex:
> +        print ex
> +        fail(EC_TOOL_FAIL)
> +
> +    process.wait()
> +
> +    out = process.communicate()
> +    process.stdout.close()
> +
> +    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"])
> +
> +    if options["log"] >= LOG_MODE_VERBOSE:
> +        options["debug_fh"].write("executing: " + cmd + "\n")
> +
> +    null = open('/dev/null', 'w')
> +    try:
> +        process = subprocess.Popen(shlex.split(cmd), stdout=null, stderr=null)
> +    except OSError:
> +        null.close()
> +        fail(EC_TOOL_FAIL)
> +
> +    process.wait()
> +    null.close()
> +
> +    return
> +
> +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 get_ipmitool_path():
> +    for path in PATHS:
> +        if is_executable(path):
> +            return path
> +    return None
> +
> +def create_command(options, action):    
> +    cmd = options["ipmitool_path"]
> +
> +    # --lanplus / -L
> +    if options.has_key("--lanplus"):
> +        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" : "L",
> +        "longopt" : "lanplus",
> +        "help" : "-L, --lanplus    Use Lanplus to improve security of connection",
> +        "required" : "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.",
> +        "default" : "none",
> +        "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" : "P:",
> +        "longopt" : "privlvl",
> +        "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
> +        }
> +
> +def main():
> +
> +    atexit.register(atexit_handler)
> +
> +    device_opt = [ "ipaddr", "login", "no_login", "no_password", "passwd", "lanplus", "auth", "cipher", "privlvl", "sudo"]
> +    define_new_opts()
> +
> +    all_opt["ipport"]["default"] = "623"
> +
> +    options = check_input(device_opt, process_input(device_opt))
> +    options["ipmitool_path"] = get_ipmitool_path()
> +
> +    if options["ipmitool_path"] is None:
> +        fail(EC_TOOL_FAIL)
> +
> +    docs = { }
> +    docs["shortdesc"] = "Fence agent for IPMI"
> +    docs["longdesc"] = "Fence agent for IPMI"
> +    docs["vendorurl"] = ""
> +    show_docs(options, docs)
> +
> +    result = fence_action(None, options, set_power_status, get_power_status, None)
> +
> +    sys.exit(result)
> +
> +if __name__ == "__main__":
> +    main()
> diff --git a/fence/agents/lib/fencing.py.py b/fence/agents/lib/fencing.py.py
> index 0a3b122..b4abfb2 100644
> --- a/fence/agents/lib/fencing.py.py
> +++ b/fence/agents/lib/fencing.py.py
> @@ -25,6 +25,7 @@ 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"
> @@ -412,7 +413,8 @@ 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_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."
>  	}[error_code] + "\n"
>  	sys.stderr.write(message)
>  	syslog.syslog(syslog.LOG_ERR, message)
> 




More information about the Cluster-devel mailing list