mirror of
https://github.com/xcat2/xcat-core.git
synced 2025-05-22 03:32:04 +00:00
rspconfig dump in python
This commit is contained in:
parent
41c86021be
commit
bfc367cb88
@ -37,6 +37,29 @@ class RestSession(object):
|
||||
|
||||
return response
|
||||
|
||||
def request_download(self, method, url, headers, file_path, using_curl=False):
|
||||
|
||||
if using_curl:
|
||||
response = self._download_by_curl(method, url, headers, file_path)
|
||||
else:
|
||||
response = self.session.request('GET', url, headers=headers)
|
||||
file_handle = open(file_path, "wb")
|
||||
for chunk in response.iter_content(chunk_size=1024):
|
||||
if chunk:
|
||||
file_handle.write(chunk)
|
||||
|
||||
return response
|
||||
|
||||
def _download_by_curl(self, method, url, headers, file_path):
|
||||
|
||||
header_str = ' '.join([ "%s: %s" % (k, v) for k,v in headers.items() ])
|
||||
request_cmd = 'curl -J -k -b sid=%s -H "%s" -X %s -o %s %s -s' % \
|
||||
(self.cookies['sid'], header_str, method, file_path, url)
|
||||
|
||||
sub = Popen(request_cmd, stdout=PIPE, shell=True)
|
||||
response, err = sub.communicate()
|
||||
return response
|
||||
|
||||
def request_upload(self, method, url, headers, files, using_curl=True):
|
||||
if using_curl:
|
||||
return self._upload_by_curl(method, url, headers, files)
|
||||
|
@ -16,11 +16,11 @@ class BmcConfigInterface(object):
|
||||
def dump_generate(self, task):
|
||||
return task.run("dump_generate")
|
||||
|
||||
def dump_clear(self, task, id):
|
||||
return task.run("dump_clear", id)
|
||||
def dump_clear(self, task, clear_arg):
|
||||
return task.run("dump_clear", clear_arg)
|
||||
|
||||
def dump_download(self, task, id):
|
||||
return task.run("dump_download", id)
|
||||
def dump_download(self, task, download_arg):
|
||||
return task.run("dump_download", download_arg)
|
||||
|
||||
def dump_process(self, task):
|
||||
return task.run("dump_process")
|
||||
|
@ -5,6 +5,7 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
from __future__ import print_function
|
||||
import os, stat
|
||||
import gevent
|
||||
import time
|
||||
|
||||
@ -18,22 +19,157 @@ logger = logging.getLogger('xcatagent')
|
||||
RSPCONFIG_GET_NETINFO=['ip', 'netmask', 'gateway', 'vlan', 'ipsrc', 'hostname']
|
||||
RSPCONFIG_SET_NETINFO=['ip', 'netmask', 'gateway', 'vlan']
|
||||
|
||||
XCAT_LOG_DUMP_DIR = "/var/log/xcat/dump/"
|
||||
|
||||
class OpenBMCBmcConfigTask(ParallelNodesCommand):
|
||||
|
||||
|
||||
def pre_dump_download(self, task, download_arg, **kw):
|
||||
|
||||
if download_arg == 'all':
|
||||
self.callback.info('Downloading all dumps...')
|
||||
if not os.path.exists(XCAT_LOG_DUMP_DIR):
|
||||
os.makedirs(XCAT_LOG_DUMP_DIR)
|
||||
|
||||
def pre_dump_process(self, task, **kw):
|
||||
|
||||
self.callback.info('Capturing BMC Diagnostic information, this will take some time...')
|
||||
|
||||
def _dump_download(self, obmc, node, download_id, flag_dump_process=False):
|
||||
|
||||
formatted_time = time.strftime("%Y%m%d-%H%M", time.localtime(time.time()))
|
||||
dump_log_file = '%s%s_%s_dump_%s.tar.xz' % (XCAT_LOG_DUMP_DIR, formatted_time, node, download_id)
|
||||
if flag_dump_process:
|
||||
self.callback.info('%s: Downloading dump %s to %s' % (node, download_id, dump_log_file))
|
||||
|
||||
obmc.download_dump(download_id, dump_log_file)
|
||||
if os.path.exists(dump_log_file):
|
||||
grep_cmd = '/usr/bin/grep -a'
|
||||
path_not_found = '"Path not found"'
|
||||
check_cmd = grep_cmd + ' ' + path_not_found + ' ' + dump_log_file
|
||||
grep_string = os.popen(check_cmd).readlines()
|
||||
if grep_string:
|
||||
result = 'Invalid dump %s was specified. Use -l option to list.' % download_id
|
||||
else:
|
||||
result = 'Downloaded dump %s to %s.' % (download_id, dump_log_file)
|
||||
else:
|
||||
result = 'Failed to download dump %s to %s.' % (download_id, dump_log_file)
|
||||
return result
|
||||
|
||||
def dump_list(self, **kw):
|
||||
return self.callback.info('dump_list')
|
||||
|
||||
node = kw['node']
|
||||
obmc = openbmc.OpenBMCRest(name=node, nodeinfo=kw['nodeinfo'], messager=self.callback,
|
||||
debugmode=self.debugmode, verbose=self.verbose)
|
||||
|
||||
dump_info = []
|
||||
try:
|
||||
obmc.login()
|
||||
dump_dict = obmc.list_dump_info()
|
||||
|
||||
if not dump_dict:
|
||||
self.callback.info('%s: No attributes returned from the BMC.' % node)
|
||||
|
||||
keys = dump_dict.keys()
|
||||
keys.sort()
|
||||
for key in keys:
|
||||
info = '[%d] Generated: %s, Size: %s' % \
|
||||
(key, dump_dict[key]['Generated'], dump_dict[key]['Size'])
|
||||
dump_info += info
|
||||
self.callback.info('%s: %s' % (node, info))
|
||||
|
||||
except (SelfServerException, SelfClientException) as e:
|
||||
self.callback.info('%s: %s' % (node, e.message))
|
||||
|
||||
return dump_info
|
||||
|
||||
def dump_generate(self, **kw):
|
||||
return self.callback.info("dump_generate")
|
||||
|
||||
def dump_clear(self, id, **kw):
|
||||
return self.callback.info("dump_clear id: %s" % id)
|
||||
node = kw['node']
|
||||
obmc = openbmc.OpenBMCRest(name=node, nodeinfo=kw['nodeinfo'], messager=self.callback,
|
||||
debugmode=self.debugmode, verbose=self.verbose)
|
||||
|
||||
def dump_download(self, id, **kw):
|
||||
return self.callback.info("dump_download id: %s" % id)
|
||||
dump_id = None
|
||||
try:
|
||||
obmc.login()
|
||||
dump_id = obmc.create_dump()
|
||||
if not dump_id:
|
||||
self.callback.info('%s: BMC returned 200 OK but no ID was returned. Verify manually on the BMC.' % node)
|
||||
else:
|
||||
self.callback.info('%s: [%s] success' % (node, dump_id))
|
||||
except (SelfServerException, SelfClientException) as e:
|
||||
self.callback.info('%s: %s' % (node, e.message))
|
||||
|
||||
return dump_id
|
||||
|
||||
def dump_clear(self, clear_arg, **kw):
|
||||
|
||||
node = kw['node']
|
||||
obmc = openbmc.OpenBMCRest(name=node, nodeinfo=kw['nodeinfo'], messager=self.callback,
|
||||
debugmode=self.debugmode, verbose=self.verbose)
|
||||
|
||||
try:
|
||||
obmc.login()
|
||||
obmc.clear_dump(clear_arg)
|
||||
|
||||
result = '%s: [%s] clear' % (node, clear_arg)
|
||||
except (SelfServerException, SelfClientException) as e:
|
||||
result = '%s: %s' % (node, e.message)
|
||||
|
||||
self.callback.info(result)
|
||||
|
||||
def dump_download(self, download_arg, **kw):
|
||||
|
||||
node = kw['node']
|
||||
obmc = openbmc.OpenBMCRest(name=node, nodeinfo=kw['nodeinfo'], messager=self.callback,
|
||||
debugmode=self.debugmode, verbose=self.verbose)
|
||||
|
||||
try:
|
||||
obmc.login()
|
||||
if download_arg != 'all':
|
||||
result = self._dump_download(obmc, node, download_arg)
|
||||
self.callback.info('%s: %s' % (node, result))
|
||||
return
|
||||
|
||||
dump_dict = obmc.list_dump_info()
|
||||
keys = dump_dict.keys()
|
||||
keys.sort()
|
||||
|
||||
for key in keys:
|
||||
result = self._dump_download(obmc, node, str(key))
|
||||
self.callback.info('%s: %s' % (node, result))
|
||||
except SelfServerException as e:
|
||||
self.callback.info('%s: %s' % (node, e.message))
|
||||
|
||||
def dump_process(self, **kw):
|
||||
return self.callback.info("dump_process: trigger, list and download")
|
||||
|
||||
node = kw['node']
|
||||
obmc = openbmc.OpenBMCRest(name=node, nodeinfo=kw['nodeinfo'], messager=self.callback,
|
||||
debugmode=self.debugmode, verbose=self.verbose)
|
||||
|
||||
try:
|
||||
obmc.login()
|
||||
flag = False
|
||||
dump_id = obmc.create_dump()
|
||||
self.callback.info('%s: Dump requested. Target ID is %s, waiting for BMC to generate...' % (node, dump_id))
|
||||
for i in range(20):
|
||||
dump_dict = obmc.list_dump_info()
|
||||
if dump_id in dump_dict:
|
||||
flag = True
|
||||
break
|
||||
if (20-i) % 8 == 0:
|
||||
self.callback.info('%s: Still waiting for dump %s to be generated... ' % (node, dump_id))
|
||||
|
||||
gevent.sleep( 15 )
|
||||
|
||||
if flag:
|
||||
result = self._dump_download(obmc, node, str(dump_id), flag_dump_process=True)
|
||||
else:
|
||||
result = 'Could not find dump %s after waiting %d seconds.' % (dump_id, 20 * 15)
|
||||
|
||||
self.callback.info('%s: %s' % (node, result))
|
||||
|
||||
except SelfServerException as e:
|
||||
self.callback.info('%s: %s' % (node, e.message))
|
||||
|
||||
def set_sshcfg(self, **kw):
|
||||
return self.callback.info("set_sshcfg")
|
||||
|
@ -9,7 +9,7 @@ import requests
|
||||
import json
|
||||
import time
|
||||
|
||||
from common import rest
|
||||
from common import utils, rest
|
||||
from common.exceptions import SelfClientException, SelfServerException
|
||||
|
||||
import logging
|
||||
@ -29,6 +29,23 @@ RBEACON_URLS = {
|
||||
},
|
||||
}
|
||||
|
||||
DUMP_URLS = {
|
||||
"clear" : {
|
||||
"path" : "/dump/entry/#ID#/action/Delete",
|
||||
"field" : [],
|
||||
},
|
||||
"clear_all" : {
|
||||
"path" : "/dump/action/DeleteAll",
|
||||
"field" : [],
|
||||
},
|
||||
"create" : {
|
||||
"path" : "/dump/action/CreateDump",
|
||||
"field" : [],
|
||||
},
|
||||
"download" : "download/dump/#ID#",
|
||||
"list" : "/dump/enumerate",
|
||||
}
|
||||
|
||||
INVENTORY_URL = "/inventory/enumerate"
|
||||
|
||||
LEDS_URL = "/led/physical/enumerate"
|
||||
@ -209,6 +226,7 @@ class OpenBMCRest(object):
|
||||
|
||||
self.session = rest.RestSession()
|
||||
self.root_url = HTTP_PROTOCOL + self.bmcip + PROJECT_URL
|
||||
self.download_root_url = HTTP_PROTOCOL + self.bmcip + '/'
|
||||
|
||||
def _print_record_log (self, msg, cmd):
|
||||
|
||||
@ -218,13 +236,16 @@ class OpenBMCRest(object):
|
||||
self.messager.info(localtime + ' ' + log)
|
||||
logger.debug(log)
|
||||
|
||||
def _log_request (self, method, url, headers, data=None, files=None, cmd=''):
|
||||
def _log_request (self, method, url, headers, data=None, files=None, file_path=None, cmd=''):
|
||||
|
||||
header_str = ' '.join([ "%s: %s" % (k, v) for k,v in headers.items() ])
|
||||
msg = 'curl -k -c cjar -b cjar -X %s -H \"%s\" ' % (method, header_str)
|
||||
|
||||
if files:
|
||||
msg += '-T \'%s\' %s -s' % (files, url)
|
||||
elif file_path:
|
||||
msg = 'curl -J -k -c cjar -b cjar -X %s -H \"%s\" %s -o %s' % \
|
||||
(method, header_str, url, file_path)
|
||||
elif data:
|
||||
if cmd == 'login':
|
||||
data = data.replace(self.password, "xxxxxx")
|
||||
@ -273,6 +294,32 @@ class OpenBMCRest(object):
|
||||
self._print_record_log(error, cmd)
|
||||
raise SelfServerException(error)
|
||||
|
||||
def download(self, method, resource, file_path, headers=None, cmd=''):
|
||||
|
||||
httpheaders = headers or OpenBMCRest.headers
|
||||
url = resource
|
||||
if not url.startswith(HTTP_PROTOCOL):
|
||||
url = self.download_root_url + resource
|
||||
|
||||
request_cmd = self._log_request(method, url, httpheaders, file_path=file_path, cmd=cmd)
|
||||
|
||||
try:
|
||||
response = self.session.request_download(method, url, httpheaders, file_path)
|
||||
except SelfServerException as e:
|
||||
self._print_record_log(e.message, cmd=cmd)
|
||||
raise
|
||||
except SelfClientException as e:
|
||||
error = e.message
|
||||
self._print_record_log(error, cmd=cmd)
|
||||
raise
|
||||
|
||||
if not response:
|
||||
self._print_record_log('No response received', cmd=cmd)
|
||||
return True
|
||||
|
||||
self._print_record_log(str(response.status_code), cmd=cmd)
|
||||
return True
|
||||
|
||||
def upload (self, method, resource, files, headers=None, cmd=''):
|
||||
|
||||
httpheaders = headers or OpenBMCRest.headers
|
||||
@ -511,6 +558,48 @@ class OpenBMCRest(object):
|
||||
data={"data": attr_info['get_data']}
|
||||
return self.request(method, get_url, payload=data, cmd="get_%s" % key)
|
||||
|
||||
def clear_dump(self, clear_arg):
|
||||
|
||||
if clear_arg == 'all':
|
||||
payload = { "data": DUMP_URLS['clear_all']['field'] }
|
||||
self.request('POST', DUMP_URLS['clear_all']['path'], payload=payload, cmd='clear_dump_all')
|
||||
else:
|
||||
path = DUMP_URLS['clear']['path'].replace('#ID#', clear_arg)
|
||||
payload = { "data": DUMP_URLS['clear']['field'] }
|
||||
self.request('POST', path, payload=payload, cmd='clear_dump')
|
||||
|
||||
def create_dump(self):
|
||||
|
||||
payload = payload = { "data": DUMP_URLS['create']['field'] }
|
||||
return self.request('POST', DUMP_URLS['create']['path'], payload=payload, cmd='create_dump')
|
||||
|
||||
def list_dump_info(self):
|
||||
|
||||
dump_data = self.request('GET', DUMP_URLS['list'], cmd='list_dump_info')
|
||||
|
||||
try:
|
||||
dump_dict = {}
|
||||
for key, value in dump_data.items():
|
||||
if 'Size' not in value or 'Elapsed' not in value:
|
||||
continue
|
||||
|
||||
key_id = int(key.split('/')[-1])
|
||||
timestamp = value['Elapsed']
|
||||
gen_time = time.strftime("%m/%d/%Y %H:%M:%S", time.localtime(timestamp))
|
||||
dump_dict.update({key_id: {'Size': value['Size'], 'Generated': gen_time}})
|
||||
|
||||
return dump_dict
|
||||
except KeyError:
|
||||
error = 'Error: Received wrong format response: %s' % inventory_data
|
||||
raise SelfServerException(error)
|
||||
|
||||
def download_dump(self, download_id, file_path):
|
||||
|
||||
headers = {'Content-Type': 'application/octet-stream'}
|
||||
path = DUMP_URLS['download'].replace('#ID#', download_id)
|
||||
self.download('GET', path, file_path, headers=headers, cmd='download_dump')
|
||||
|
||||
|
||||
class OpenBMCImage(object):
|
||||
def __init__(self, rawid, data=None):
|
||||
self.id = rawid.split('/')[-1]
|
||||
|
@ -724,9 +724,9 @@ class OpenBMCManager(base.BaseManager):
|
||||
elif opts['--generate']:
|
||||
DefaultBmcConfigManager().dump_generate(runner)
|
||||
elif opts['--clear']:
|
||||
DefaultBmcConfigManager().dump_clear(runner, opts['--clear'])
|
||||
DefaultBmcConfigManager().dump_clear(runner, opts['--clear'][0])
|
||||
elif opts['--download']:
|
||||
DefaultBmcConfigManager().dump_download(runner, opts['--download'])
|
||||
DefaultBmcConfigManager().dump_download(runner, opts['--download'][0])
|
||||
else:
|
||||
DefaultBmcConfigManager().dump_process(runner)
|
||||
elif opts['sshcfg']:
|
||||
|
Loading…
x
Reference in New Issue
Block a user