2
0
mirror of https://github.com/xcat2/confluent.git synced 2024-11-25 11:01:09 +00:00

Refactor plugin code to better assure all things happen in one greenthread

Additionally, begin work to make ipmi.py start doing non-console things
This commit is contained in:
Jarrod Johnson 2013-10-12 15:13:34 -04:00
parent 1c2341e1eb
commit 5e80407bc5

View File

@ -3,6 +3,7 @@ import eventlet
import eventlet.event
import os
import pyghmi.ipmi.console as console
import pyghmi.ipmi.command as ipmicommand
console.session.select = eventlet.green.select
_ipmithread = None
@ -12,6 +13,13 @@ chainpulled = False
tmptimeout = None
ipmiq = collections.deque([])
ipmiwaiters = collections.deque([])
ipmisessions = {}
def wait_on_ipmi():
waitevt = eventlet.event.Event()
ipmiwaiters.append(waitevt)
waitevt.wait()
def _ipmi_evtloop():
@ -30,13 +38,22 @@ def _ipmi_evtloop():
waiter.send()
def _process_chgs(intline):
#here we receive functions to run in our thread
#the tuples on the deque consist of:
#function, arg tuple, and optionally a callback
#to send the return value back to the requester
global chainpulled
os.read(intline,1) # answer the bell
chainpulled = False
while ipmiq:
cval = ipmiq.popleft()
if hasattr(cval[0], '__call__'):
cval[0](*cval[1])
if isinstance(cval[1], tuple):
rv = cval[0](*cval[1])
elif isinstance(cval[1], dict):
rv = cval[0](**cval[1])
if len(cval) > 2:
cval[2](rv)
@ -91,16 +108,35 @@ class Console(object):
def connect(self,callback):
global _ipmithread
global pullchain
self.solconnection = console.Console(bmc=self.bmc,
port=self.port,
userid=self.username,
password=self.password,
kg=self.kg,
force=True,
iohandler=callback)
global ipmisessions
global chainpulled
try:
ipmisession = ipmisessions[(self.bmc, self.port)]
except KeyError:
ipmisession = None
if _ipmithread is None:
pullchain = os.pipe()
_ipmithread = eventlet.spawn(_ipmi_evtloop)
self.solconnection = None
ipmiq.append((console.Console,{'bmc': self.bmc,
'port': self.port,
'userid': self.username,
'password': self.password,
'kg': self.kg,
'force': True,
'ipmisession': ipmisession,
'iohandler': callback}, self.got_consobject))
if not chainpulled:
chainpulled = True
os.write(pullchain[1],'1')
while self.solconnection is None:
wait_on_ipmi()
if ipmisession is None:
ipmisessions[(self.bmc, self.port)] = \
self.solconnection.ipmi_session
def got_consobject(self, solconnection):
self.solconnection = solconnection
def write(self, data):
global chainpulled
@ -130,15 +166,81 @@ class Console(object):
chainpulled=True
os.write(pullchain[1],'1')
eventlet.sleep(0.001)
waitevt = eventlet.event.Event()
ipmiwaiters.append(waitevt)
waitevt.wait()
wait_on_ipmi()
#TODO: a channel for the ipmithread to tug back instead of busy wait
#while tmptimeout is not None:
# eventlet.sleep(0)
#console.session.Session.wait_for_rsp(timeout=timeout)
class IpmiIterator(object):
def __init__(self, operator, nodes, element, cfg):
configdata = cfg.get_node_attributes(nodes,
['secret.ipmiuser', 'secret.ipmipassphrase',
'secret.managementuser', 'secret.managementpassphrase',
'hardwaremanagement.manager'])
for node in nodes:
IpmiHandler(operator, node, element, configdata)
def __iter__(self):
return self
def next(self):
pass
class IpmiHandler(object):
def __iter__():
return self
def __init__(self, operation, node, element, cfd):
self.cfg = cfd[node]
self.node = node
self.element = element
self.op = operation
connparams = get_conn_params(node, self.cfg)
self.ipmicmd = None
try:
ipmisession = ipmisessions[(self.bmc, self.port)]
except KeyError:
ipmisession = None
ipmiq.append((ipmicommand.Command,{'bmc': connparams['bmc'],
'userid': connparams['username'],
'password': connparams['passphrase'],
'kg': connparams['kg'],
'port': connparams['port'],
'onlogon': self.handle_request,
'ipmisession': ipmisession},
got_ipmicmd))
while self.ipmicmd == None:
wait_on_ipmi()
if ipmisession is None:
ipmisessions[(self.bmc, self.port)] = self.ipmicmd.ipmi_session
def got_ipmicmd(self, ipmicmd):
self.ipmicmd = ipmicmd
def call_ipmicmd(self, function, *args):
self.lastrsp = None
ipmiq.append((function, args, self.got_rsp))
while self.lastrsp is None:
wait_on_ipmi()
return self.lastrsp
def got_rsp(self, response):
self.lastrsp = response
def handle_request(self, response):
if 'error' in response:
raise Exception(response['error'])
if self.element == 'power/state':
if 'read' == self.op:
rsp = self.call_ipmi(self.ipmicmd.get_power)
print(rsp)
def create(nodes, element, configmanager):
if element == '_console/session':
if len(nodes) > 1:
@ -149,5 +251,6 @@ def create(nodes, element, configmanager):
"TODO(jbjohnso): ipmi api implementation of %s" % element)
def retrieve(nodes, element, configmanager):
raise Exception("TODO(jbjohnso): ipmi get implementation of %s" % element)
pass