mirror of
				https://github.com/xcat2/xcat-core.git
				synced 2025-10-31 03:12:30 +00:00 
			
		
		
		
	rspconfig dump in python
This commit is contained in:
		| @@ -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']: | ||||
|   | ||||
		Reference in New Issue
	
	Block a user