mirror of
				https://github.com/xcat2/xcat-core.git
				synced 2025-10-31 19:32:31 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			98 lines
		
	
	
		
			3.3 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			98 lines
		
	
	
		
			3.3 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
| #!/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 sys
 | |
| import traceback
 | |
| 
 | |
| class BaseCommand(object):
 | |
| 
 | |
|     def _validate(self, op, *args, **kw):
 | |
|         if hasattr(self, 'validate_%s' % op):
 | |
|             return getattr(self, 'validate_%s' % op)(self, *args, **kw)
 | |
| 
 | |
|     def _pre(self, op, *args, **kw):
 | |
|         if hasattr(self, 'pre_%s' % op):
 | |
|             return getattr(self, 'pre_%s' % op)(self, *args, **kw)
 | |
| 
 | |
|     def _execute(self, op, *args, **kw):
 | |
|         if hasattr(self, '%s' % op):
 | |
|             return getattr(self, '%s' % op)(self, *args, **kw)
 | |
| 
 | |
|     def _post(self, op, *args, **kw):
 | |
|         if hasattr(self, 'post_%s' % op):
 | |
|             return getattr(self, 'post_%s' % op)(self, *args, **kw)
 | |
| 
 | |
|     def run(self, op, *args, **kwargs):
 | |
|         #print 'op=%s, args=%s, kwargs=%s' % (op, args, kwargs)
 | |
|         try:
 | |
|             self._validate(op, *args, **kwargs)
 | |
|             self._pre(op, *args, **kwargs)
 | |
|             self._execute(op, *args, **kwargs)
 | |
|             self._post(op, *args, **kwargs)
 | |
|         except Exception as e:
 | |
|             # TODO: put e into log
 | |
|             print(traceback.format_exc(), file=sys.stderr)
 | |
|             return None
 | |
| 
 | |
|         return self.result()
 | |
| 
 | |
|     def result(self):
 | |
|         """Assume the result will be set by *_<op>"""
 | |
|         return True
 | |
| 
 | |
| class ParallelNodesCommand(BaseCommand):
 | |
| 
 | |
|     def __init__(self, inventory, callback=None, **kwargs):
 | |
|         """
 | |
|         inventory: {'node1': {k1:v1, k2:v2, ...}, 'node2': ...}
 | |
|         """
 | |
|         self.inventory = inventory
 | |
|         self.callback = callback
 | |
|         self.cwd = kwargs.get('cwd')
 | |
|         self.debugmode = kwargs.get('debugmode')
 | |
|         self.verbose = kwargs.get('verbose')
 | |
| 
 | |
|     def _execute_in_parallel(self, op, *args, **kw):
 | |
|         if not hasattr(self, '%s' % op):
 | |
|             return
 | |
| 
 | |
|         assert self.inventory and type(self.inventory) is dict
 | |
|         func = getattr(self, '%s' % op)
 | |
|         if len(self.inventory) == 1:
 | |
|             node = list(self.inventory.keys())[0]
 | |
|             func(*args, node=node, nodeinfo=self.inventory[node], **kw)
 | |
|             return
 | |
| 
 | |
|         pool_size = 1000 # Get it from kw later
 | |
|         gevent_pool = gevent.pool.Pool(pool_size)
 | |
| 
 | |
|         for node in self.inventory.keys():
 | |
|             try:
 | |
|                 gevent_pool.add( gevent.spawn(func, *args, node=node, nodeinfo=self.inventory[node], **kw))
 | |
|             except Exception as e:
 | |
|                 error = '%s: Internel Error occured in gevent' % node
 | |
|                 #print(traceback.format_exc(), file=sys.stderr)
 | |
|                 self.callback.error(error)
 | |
| 
 | |
|         gevent_pool.join()
 | |
| 
 | |
|     def run(self, op, *args, **kwargs):
 | |
|         #print 'op=%s, args=%s, kwargs=%s' % (op, args, kwargs)
 | |
|         try:
 | |
|             self._validate(op, *args, **kwargs)
 | |
|             self._pre(op, *args, **kwargs)
 | |
|             self._execute_in_parallel(op, *args, **kwargs)
 | |
|             self._post(op, *args, **kwargs)
 | |
|         except Exception as e:
 | |
|             # TODO: put e into log
 | |
|             print(traceback.format_exc(), file=sys.stderr)
 | |
|             return None
 | |
| 
 | |
|         return self.result()
 |