| #!/usr/bin/python |
| # Licensed to the Apache Software Foundation (ASF) under one |
| # or more contributor license agreements. See the NOTICE file |
| # distributed with this work for additional information |
| # regarding copyright ownership. The ASF licenses this file |
| # to you under the Apache License, Version 2.0 (the |
| # "License"); you may not use this file except in compliance |
| # with the License. You may obtain a copy of the License at |
| # |
| # http://www.apache.org/licenses/LICENSE-2.0 |
| # |
| # Unless required by applicable law or agreed to in writing, |
| # software distributed under the License is distributed on an |
| # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| # KIND, either express or implied. See the License for the |
| # specific language governing permissions and limitations |
| # under the License. |
| |
| |
| |
| |
| import sys, os, subprocess, errno, re |
| from os.path import exists |
| |
| TOOl_PATH = "/usr/bin/ipmitool" |
| |
| try: |
| from subprocess import check_call |
| from subprocess import CalledProcessError |
| except ImportError: |
| def check_call(*popenargs, **kwargs): |
| import subprocess |
| retcode = subprocess.call(*popenargs, **kwargs) |
| cmd = kwargs.get("args") |
| if cmd is None: cmd = popenargs[0] |
| if retcode: raise CalledProcessError(retcode, cmd) |
| return retcode |
| |
| class CalledProcessError(Exception): |
| def __init__(self, returncode, cmd): |
| self.returncode = returncode ; self.cmd = cmd |
| def __str__(self): return "Command '%s' returned non-zero exit status %d" % (self.cmd, self.returncode) |
| |
| class Command: |
| def __init__(self,name,parent=None): |
| self.__name = name |
| self.__parent = parent |
| def __getattr__(self,name): |
| if name == "_print": name = "print" |
| return Command(name,self) |
| def __call__(self,*args): |
| class CommandOutput: |
| def __init__(self,ret,stdout,stderr): |
| self.stdout = stdout |
| self.stderr = stderr |
| self.ret = ret |
| |
| cmd = self.__get_recursive_name() + list(args) |
| #print " ",cmd |
| popen = subprocess.Popen(cmd,stdout=subprocess.PIPE,stderr=subprocess.PIPE) |
| m = popen.communicate() |
| ret = popen.wait() |
| return CommandOutput(ret,*m) |
| def __get_recursive_name(self,sep=None): |
| m = self |
| l = [] |
| while m is not None: |
| l.append(m.__name) |
| m = m.__parent |
| l.reverse() |
| if sep: return sep.join(l) |
| else: return l |
| def __str__(self): |
| return '<Command %r>'%self.__get_recursive_name(sep=" ") |
| |
| def __repr__(self): return self.__str__() |
| |
| |
| ipmitool = Command("ipmitool") |
| |
| def check_tool(): |
| if exists(TOOl_PATH) == False: |
| print "Can not find ipmitool" |
| return False |
| |
| def ping(args): |
| hostname = args.get("hostname") |
| usrname = args.get("usrname") |
| password = args.get("password") |
| |
| if hostname == None: |
| print "No hostname" |
| return 1 |
| |
| o = ipmitool("-H", hostname, "-U", usrname, "-P", password, "chassis", "power", "status") |
| if o.ret: |
| print o.stderr |
| return 1 |
| else: |
| print o.stdout |
| return 0 |
| |
| def boot_dev(args): |
| hostname = args.get("hostname") |
| usrname = args.get("usrname") |
| password = args.get("password") |
| dev = args.get("dev") |
| |
| if hostname == None: |
| print "No hostname" |
| return 1 |
| |
| if dev == None: |
| print "No boot device specified" |
| return 1 |
| |
| o = ipmitool("-H", hostname, "-U", usrname, "-P", password, "chassis", "bootdev", dev) |
| if o.ret: |
| print o.stderr |
| return 1 |
| else: |
| return 0 |
| |
| def reboot(args): |
| hostname = args.get("hostname") |
| usrname = args.get("usrname") |
| password = args.get("password") |
| |
| if hostname == None: |
| print "No hostname" |
| return 1 |
| |
| o = ipmitool("-H", hostname, "-U", usrname, "-P", password, "chassis", "power", "status") |
| if o.ret: |
| print o.stderr |
| return 1 |
| |
| |
| if "is on" in o.stdout: |
| o = ipmitool("-H", hostname, "-U", usrname, "-P", password, "chassis", "power", "cycle") |
| else: |
| o = ipmitool("-H", hostname, "-U", usrname, "-P", password, "chassis", "power", "reset") |
| |
| if o.ret: |
| print o.stderr |
| return 1 |
| else: |
| return 0 |
| |
| def power(args): |
| hostname = args.get("hostname") |
| usrname = args.get("usrname") |
| password = args.get("password") |
| action = args.get("action") |
| |
| if hostname == None: |
| print "No hostname" |
| return 1 |
| |
| o = ipmitool("-H", hostname, "-U", usrname, "-P", password, "chassis", "power", action) |
| if o.ret: |
| print o.stderr |
| return 1 |
| else: |
| return 0 |
| |
| def boot_or_reboot(args): |
| hostname = args.get("hostname") |
| usrname = args.get("usrname") |
| password = args.get("password") |
| o = ipmitool("-H", hostname, "-U", usrname, "-P", password, "chassis", "power", "status") |
| if o.ret: |
| print o.stderr |
| return 1 |
| |
| if "is on" in o.stdout: |
| return reboot(args) |
| elif "is off" in o.stdout: |
| args["action"] = "on" |
| return power(args) |
| else: |
| print "unknown power status:" + o.stdout |
| return 1 |
| |
| |
| call_table = {"ping":ping, "boot_dev":boot_dev, "reboot":reboot, "power":power, "boot_or_reboot":boot_or_reboot} |
| def dispatch(args): |
| cmd = args[1] |
| params = args[2:] |
| func_params = {} |
| |
| if call_table.has_key(cmd) == False: |
| print "No function %s" % cmd |
| return 1 |
| |
| for p in params: |
| pairs = p.split("=") |
| if len(pairs) != 2: |
| print "Invalid parameter %s" % p |
| return 1 |
| func_params[pairs[0]] = pairs[1] |
| |
| func = call_table[cmd] |
| return func(func_params) |
| |
| if __name__ == "__main__": |
| if check_tool() == False: |
| sys.exit(1) |
| if len(sys.argv) < 2: |
| print "Not enough arguments, at least one" |
| sys.exit(1) |
| sys.exit(dispatch(sys.argv)) |