From 1a5795573a42b56b8e3e75e68a78f4473331de5c Mon Sep 17 00:00:00 2001 From: Bin Xu Date: Mon, 5 Feb 2018 13:03:29 +0800 Subject: [PATCH] using docopt here for arguments parsing --- .../lib/python/agent/common/utils.py | 22 ++++++++ .../lib/python/agent/hwctl/power.py | 13 ++--- .../lib/python/agent/xcatagent/openbmc.py | 54 +++++++++++-------- 3 files changed, 58 insertions(+), 31 deletions(-) diff --git a/xCAT-openbmc-py/lib/python/agent/common/utils.py b/xCAT-openbmc-py/lib/python/agent/common/utils.py index c386f0f52..69f29efcc 100644 --- a/xCAT-openbmc-py/lib/python/agent/common/utils.py +++ b/xCAT-openbmc-py/lib/python/agent/common/utils.py @@ -1,8 +1,30 @@ +#!/usr/bin/env python +############################################################################### +# IBM(c) 2018 EPL license http://www.eclipse.org/legal/epl-v10.html +############################################################################### +# -*- coding: utf-8 -*- +# import struct import sys import inspect import logging +from logging.handlers import SysLogHandler +XCAT_LOG_FMT = logging.Formatter("%(asctime)s %(levelname)s " + + "%(name)s %(process)d " + + "(%(filename)s:%(lineno)d) "+ + "%(message)s") +XCAT_LOG_FMT.datefmt = '%Y-%m-%d %H:%M:%S' + +def getxCATLog(name=None): + xl = logging.getLogger(name) + xl.fmt = XCAT_LOG_FMT + return xl + +def enableSyslog(name='xcat'): + h = SysLogHandler(address='/dev/log', facility=SysLogHandler.LOG_LOCAL4) + h.setFormatter(logging.Formatter('%s: ' % name + '%(levelname)s %(message)s')) + logging.getLogger('xcatagent').addHandler(h) def int2bytes(num): return struct.pack('i', num) diff --git a/xCAT-openbmc-py/lib/python/agent/hwctl/power.py b/xCAT-openbmc-py/lib/python/agent/hwctl/power.py index e10435b20..84b59ab99 100644 --- a/xCAT-openbmc-py/lib/python/agent/hwctl/power.py +++ b/xCAT-openbmc-py/lib/python/agent/hwctl/power.py @@ -14,7 +14,6 @@ class PowerInterface(object): """Return the power state of the task's nodes. :param task: a Task instance containing the nodes to act on. - :raises: MissingParameterValue if a required parameter is missing. :returns: a power state. """ return task.run('get_state') @@ -23,19 +22,15 @@ class PowerInterface(object): """Set the power state of the task's nodes. :param task: a Task instance containing the nodes to act on. - :param power_state: Any power state from :mod:`ironic.common.states`. + :param power_state: Any supported power state. :param timeout: timeout (in seconds) positive integer (> 0) for any power state. ``None`` indicates to use default timeout. - :raises: MissingParameterValue if a required parameter is missing. """ return task.run('set_state', power_state, timeout=timeout) def reboot(self, task, optype='boot', timeout=None): """Perform a hard reboot of the task's nodes. - Drivers are expected to properly handle case when node is powered off - by powering it on. - :param task: a Task instance containing the node to act on. :param timeout: timeout (in seconds) positive integer (> 0) for any power state. ``None`` indicates to use default timeout. @@ -46,16 +41,14 @@ class PowerInterface(object): """Return the bmc state of the task's nodes. :param task: a Task instance containing the nodes to act on. - :raises: MissingParameterValue if a required parameter is missing. - :returns: a power state. + :returns: a bmc state. """ return task.run('get_bmcstate') def reboot_bmc(self, task, optype='warm'): - """Return the bmc state of the task's nodes. + """Set the BMC state of the task's nodes. :param task: a Task instance containing the nodes to act on. - :raises: MissingParameterValue if a required parameter is missing. :returns: a power state. """ return task.run('reboot_bmc', optype) diff --git a/xCAT-openbmc-py/lib/python/agent/xcatagent/openbmc.py b/xCAT-openbmc-py/lib/python/agent/xcatagent/openbmc.py index 004a392bc..f7f877ada 100644 --- a/xCAT-openbmc-py/lib/python/agent/xcatagent/openbmc.py +++ b/xCAT-openbmc-py/lib/python/agent/xcatagent/openbmc.py @@ -5,11 +5,11 @@ # -*- coding: utf-8 -*- # -import argparse import os import time import sys import gevent +from docopt import docopt from common import utils from common import exceptions as xcat_exception @@ -18,6 +18,10 @@ from hwctl.power import DefaultPowerManager from xcatagent import base import openbmc_rest +import logging +logger = logging.getLogger('xcatagent') +if not logger.handlers: + utils.enableSyslog('xcat.agent') HTTP_PROTOCOL = "https://" PROJECT_URL = "/xyz/openbmc_project" @@ -524,43 +528,51 @@ class OpenBMCManager(base.BaseManager): super(OpenBMCManager, self).__init__(messager, cwd) self.nodes = nodes self.debugmode = (envs and envs.get('debugmode')) or None - #TODO, remove the global variable DEBUGMODE global DEBUGMODE DEBUGMODE = envs['debugmode'] + if self.debugmode: + logger.setLevel(logging.DEBUG) + def rpower(self, nodesinfo, args): # 1, parse args - parser = argparse.ArgumentParser(description='Handle rpower operations.') - parser.add_argument('--action', - help="rpower subcommand.") - parser.add_argument('-V', '--verbose', action='store_true', - help="rpower verbose mode.") - args.insert(0,'--action') - opts = parser.parse_args(args) + rpower_usage = """ + Usage: + rpower [-V|--verbose] [on|off|softoff|reset|boot|bmcreboot|bmcstate|stat|state|status] - # 2, validate the args - if opts.action is None: - self.messager.error("Not specify the subcommand for rpower") + Options: + -V --verbose rpower verbose mode. + """ + + try: + opts=docopt(rpower_usage, argv=args) + + self.verbose=opts.pop('--verbose') + action=[k for k,v in opts.items() if v][0] + except Exception as e: + # It will not be here as perl has validation for args + self.messager.error("Failed to parse arguments for rpower: %s" % args) return - if opts.action not in (POWER_GET_OPTIONS + POWER_SET_OPTIONS + POWER_REBOOT_OPTIONS): - self.messager.error("Not supported subcommand for rpower: %s" % opts.action) + # 2, validate the args + if action not in (POWER_GET_OPTIONS + POWER_SET_OPTIONS + POWER_REBOOT_OPTIONS): + self.messager.error("Not supported subcommand for rpower: %s" % action) return # 3, run the subcommands - runner = OpenBMCPowerTask(nodesinfo, callback=self.messager, debugmode=self.debugmode, verbose=opts.verbose) - if opts.action == 'bmcstate': + runner = OpenBMCPowerTask(nodesinfo, callback=self.messager, debugmode=self.debugmode, verbose=self.verbose) + if action == 'bmcstate': DefaultPowerManager().get_bmc_state(runner) - elif opts.action == 'bmcreboot': + elif action == 'bmcreboot': DefaultPowerManager().reboot_bmc(runner) - elif opts.action in POWER_GET_OPTIONS: + elif action in POWER_GET_OPTIONS: DefaultPowerManager().get_power_state(runner) - elif opts.action in POWER_REBOOT_OPTIONS: - DefaultPowerManager().reboot(runner, optype=opts.action) + elif action in POWER_REBOOT_OPTIONS: + DefaultPowerManager().reboot(runner, optype=action) else: - DefaultPowerManager().set_power_state(runner, power_state=opts.action) + DefaultPowerManager().set_power_state(runner, power_state=action) def _get_full_path(self,file_path): if type(self.cwd) == 'unicode':