From f499b21f67a179856a9f23bb66804962b855cb60 Mon Sep 17 00:00:00 2001 From: Mark Gurevich Date: Tue, 20 Feb 2018 16:03:57 -0500 Subject: [PATCH] Initial pass for Python reventlog --- .../lib/python/agent/hwctl/eventlog.py | 24 +++++++++++ .../agent/hwctl/executor/openbmc_eventlog.py | 32 +++++++++++++++ .../lib/python/agent/hwctl/openbmc_client.py | 14 +++++++ .../lib/python/agent/xcatagent/openbmc.py | 40 +++++++++++++++++++ .../lib/python/agent/xcatagent/server.py | 5 ++- xCAT-server/lib/xcat/plugins/openbmc2.pm | 26 ++++++++++++ 6 files changed, 139 insertions(+), 2 deletions(-) create mode 100644 xCAT-openbmc-py/lib/python/agent/hwctl/eventlog.py create mode 100644 xCAT-openbmc-py/lib/python/agent/hwctl/executor/openbmc_eventlog.py diff --git a/xCAT-openbmc-py/lib/python/agent/hwctl/eventlog.py b/xCAT-openbmc-py/lib/python/agent/hwctl/eventlog.py new file mode 100644 index 000000000..e5e644f17 --- /dev/null +++ b/xCAT-openbmc-py/lib/python/agent/hwctl/eventlog.py @@ -0,0 +1,24 @@ +#!/usr/bin/env python +############################################################################### +# IBM(c) 2018 EPL license http://www.eclipse.org/legal/epl-v10.html +############################################################################### +# -*- coding: utf-8 -*- +# + +class EventlogInterface(object): + """Interface for eventlog-related actions.""" + interface_type = 'eventlog' + version = '1.0' + + def get_eventlog_info(self, task, eventlog_type=None): + """Return the eventlog info of the task's nodes. + + :param eventlog_type: type of eventlog info want to get. + :param task: a Task instance containing the nodes to act on. + :return eventlog list + """ + return task.run('get_ev_info', eventlog_type) + +class DefaultEventlogManager(EventlogInterface): + """Interface for eventlog-related actions.""" + pass diff --git a/xCAT-openbmc-py/lib/python/agent/hwctl/executor/openbmc_eventlog.py b/xCAT-openbmc-py/lib/python/agent/hwctl/executor/openbmc_eventlog.py new file mode 100644 index 000000000..6d5497251 --- /dev/null +++ b/xCAT-openbmc-py/lib/python/agent/hwctl/executor/openbmc_eventlog.py @@ -0,0 +1,32 @@ +#!/usr/bin/env python +############################################################################### +# IBM(c) 2018 EPL license http://www.eclipse.org/legal/epl-v10.html +############################################################################### +# -*- coding: utf-8 -*- +# + +from __future__ import print_function +import gevent +import time + +from common.task import ParallelNodesCommand +from common.exceptions import SelfClientException, SelfServerException +from hwctl import openbmc_client as openbmc +from common import utils + +import logging +logger = logging.getLogger('xcatagent') + +class OpenBMCEventlogTask(ParallelNodesCommand): + """Executor for eventlog-related actions.""" + + def get_ev_info(self, eventlog_type, **kw): + + node = kw['node'] + obmc = openbmc.OpenBMCRest(name=node, nodeinfo=kw['nodeinfo'], messager=self.callback, debugmode=self.debugmode, verbose=self.verbose) + eventlog_info = [] + try: + obmc.login() + eventlog_info_dict = obmc.get_eventlog_info() + except (SelfServerException, SelfClientException) as e: + self.callback.info('%s: %s' % (node, e.message)) diff --git a/xCAT-openbmc-py/lib/python/agent/hwctl/openbmc_client.py b/xCAT-openbmc-py/lib/python/agent/hwctl/openbmc_client.py index f1fa55057..82983b296 100644 --- a/xCAT-openbmc-py/lib/python/agent/hwctl/openbmc_client.py +++ b/xCAT-openbmc-py/lib/python/agent/hwctl/openbmc_client.py @@ -141,6 +141,8 @@ FIRM_URLS = { } } +EVENTLOG_URL = "/logging/enumerate" + RSPCONFIG_APIS = { 'autoreboot' : { 'baseurl': "/control/host0/auto_reboot/", @@ -486,6 +488,18 @@ class OpenBMCRest(object): return bool(func_list), fw_dict + def get_eventlog_info(self): + + eventlog_data = self.request('GET', EVENTLOG_URL, cmd='get_eventlog_info') + try: + eventlog_dict = {} + for key, value in eventlog_data.items(): + self.messager.info("EVENTLOG DATA: key=%s" %key) + except KeyError: + error = 'Error: Received wrong format response: %s' % eventlog_data + raise SelfServerException(error) + + def set_apis_values(self, key, value): attr_info = RSPCONFIG_APIS[key] if not attr_info.has_key('set_url'): diff --git a/xCAT-openbmc-py/lib/python/agent/xcatagent/openbmc.py b/xCAT-openbmc-py/lib/python/agent/xcatagent/openbmc.py index 621e7301f..85c26306a 100644 --- a/xCAT-openbmc-py/lib/python/agent/xcatagent/openbmc.py +++ b/xCAT-openbmc-py/lib/python/agent/xcatagent/openbmc.py @@ -20,12 +20,14 @@ from hwctl.executor.openbmc_inventory import OpenBMCInventoryTask from hwctl.executor.openbmc_power import OpenBMCPowerTask from hwctl.executor.openbmc_sensor import OpenBMCSensorTask from hwctl.executor.openbmc_bmcconfig import OpenBMCBmcConfigTask +from hwctl.executor.openbmc_eventlog import OpenBMCEventlogTask from hwctl.beacon import DefaultBeaconManager from hwctl.setboot import DefaultBootManager from hwctl.inventory import DefaultInventoryManager from hwctl.power import DefaultPowerManager from hwctl.sensor import DefaultSensorManager from hwctl.bmcconfig import DefaultBmcConfigManager +from hwctl.eventlog import DefaultEventlogManager from xcatagent import base import openbmc_rest @@ -142,6 +144,9 @@ SETBOOT_SET_OPTIONS = ('cd', 'def', 'default', 'hd', 'net') VITALS_OPTIONS = ('all', 'altitude', 'fanspeed', 'leds', 'power', 'temp', 'voltage', 'wattage') +# global variables of reventlog +EVENTLOG_OPTIONS = ('all', 'clear', 'resolved') + class OpenBMC(base.BaseDriver): headers = {'Content-Type': 'application/json'} @@ -828,6 +833,41 @@ class OpenBMCManager(base.BaseManager): else: DefaultSensorManager().get_sensor_info(runner, action) + def reventlog(self, nodesinfo, args): + + # 1, parse agrs + if not args: + args = ['all'] + + reventlog_usage = """ + Usage: + eventlog [-V|--verbose] [all|clear|resolved] + + Options: + -V --verbose eventlog verbose mode. + """ + + try: + opts = docopt(reventlog_usage, argv=args) + + self.verbose = opts.pop('--verbose') + action = [k for k,v in opts.items() if v][0] + except Exception as e: + self.messager.error("Failed to parse arguments for reventlog: %s" % args) + return + + # 2, validate the args + if action not in EVENTLOG_OPTIONS: + self.messager.error("Not supported subcommand for reventlog: %s" % action) + return + + # 3, run the subcommands + runner = OpenBMCEventlogTask(nodesinfo, callback=self.messager, debugmode=self.debugmode, verbose=self.verbose) + if action == 'resolved': + DefaultEventlogManager().get_eventlog_info(runner) + else: + DefaultEventlogManager().get_eventlog_info(runner, action) + def _get_full_path(self,file_path): if type(self.cwd) == 'unicode': dir_path = self.cwd diff --git a/xCAT-openbmc-py/lib/python/agent/xcatagent/server.py b/xCAT-openbmc-py/lib/python/agent/xcatagent/server.py index f9b16bda4..cb6ba5a41 100644 --- a/xCAT-openbmc-py/lib/python/agent/xcatagent/server.py +++ b/xCAT-openbmc-py/lib/python/agent/xcatagent/server.py @@ -94,8 +94,9 @@ class Server(object): func = getattr(manager, req['command']) # translate unicode string to normal string to avoid docopt error new_args=[] - for a in req['args']: - new_args.append(a.encode('utf-8')) + if req['args']: + for a in req['args']: + new_args.append(a.encode('utf-8')) # call the function in the specified manager func(req['nodeinfo'], new_args) # after the method returns, the request should be handled diff --git a/xCAT-server/lib/xcat/plugins/openbmc2.pm b/xCAT-server/lib/xcat/plugins/openbmc2.pm index efd38e9e0..d788b82c6 100644 --- a/xCAT-server/lib/xcat/plugins/openbmc2.pm +++ b/xCAT-server/lib/xcat/plugins/openbmc2.pm @@ -38,9 +38,14 @@ sub handled_commands { rsetboot => 'nodehm:mgt=openbmc', rvitals => 'nodehm:mgt=openbmc', rspconfig => 'nodehm:mgt=openbmc', + reventlog => 'nodehm:mgt=openbmc', }; } +# Common logging messages: +my $usage_errormsg = "Usage error."; +my $reventlog_no_id_resolved_errormsg = "Provide a comma separated list of IDs to be resolved. Example: 'resolved=x,y,z'"; + my %node_info = (); my $callback; @@ -252,6 +257,27 @@ sub parse_args { } } elsif ($command eq 'rspconfig') { xCAT_plugin::openbmc::parse_args('rspconfig', $extrargs, $noderange); + } elsif ($command eq "reventlog") { + $subcommand = "all" if (!defined($ARGV[0])); + if ($subcommand =~ /^(\w+)=(.*)/) { + my $key = $1; + my $value = $2; + if (not $value) { + return ([ 1, "$usage_errormsg $reventlog_no_id_resolved_errormsg" ]); + } + + my $nodes_num = @$noderange; + if (@$noderange > 1) { + return ([ 1, "Resolving faults over a xCAT noderange is not recommended." ]); + } + + xCAT::SvrUtils::sendmsg("Attempting to resolve the following log entries: $value...", $callback); + } elsif ($subcommand !~ /^\d$|^\d+$|^all$|^clear$/) { + if ($subcommand =~ "resolved") { + return ([ 1, "$usage_errormsg $reventlog_no_id_resolved_errormsg" ]); + } + return ([ 1, "Unsupported command: $command $subcommand" ]); + } } else { return ([ 1, "Unsupported command: $command" ]); }