xen-vtx-unstable
annotate tools/python/xen/xend/server/controller.py @ 1654:90b354900bbf
bitkeeper revision 1.1041.3.1 (40e3fe2a5JO0HpkIeSaP8q6IITbNAQ)
Documentation and a couple of tidies.
Documentation and a couple of tidies.
author | mjw@wray-m-3.hpl.hp.com |
---|---|
date | Thu Jul 01 12:06:02 2004 +0000 (2004-07-01) |
parents | 236a9f2698a3 |
children | 11fc1027833b 2e084d76fbf4 |
rev | line source |
---|---|
mjw@1654 | 1 # Copyright (C) 2004 Mike Wray <mike.wray@hp.com> |
mjw@1654 | 2 |
mjw@1623 | 3 from twisted.internet import defer |
mjw@1623 | 4 |
mjw@1623 | 5 import channel |
mjw@1623 | 6 from messages import msgTypeName |
mjw@1623 | 7 |
mjw@1623 | 8 class CtrlMsgRcvr: |
mjw@1623 | 9 """Abstract class for things that deal with a control interface to a domain. |
mjw@1654 | 10 |
mjw@1654 | 11 Instance variables: |
mjw@1654 | 12 |
mjw@1654 | 13 dom : the domain we are a control interface for |
mjw@1654 | 14 majorTypes: list of major message types we are interested in |
mjw@1654 | 15 subTypes : mapping of message subtypes to methods |
mjw@1654 | 16 |
mjw@1654 | 17 channel : channel to the domain |
mjw@1654 | 18 idx : channel index |
mjw@1623 | 19 """ |
mjw@1623 | 20 |
mjw@1623 | 21 |
mjw@1623 | 22 def __init__(self): |
mjw@1623 | 23 self.channelFactory = channel.channelFactory() |
mjw@1623 | 24 self.majorTypes = [ ] |
mjw@1623 | 25 self.subTypes = {} |
mjw@1623 | 26 self.dom = None |
mjw@1623 | 27 self.channel = None |
mjw@1623 | 28 self.idx = None |
mjw@1623 | 29 |
mjw@1623 | 30 def requestReceived(self, msg, type, subtype): |
mjw@1654 | 31 """Dispatch a request to handlers. |
mjw@1654 | 32 |
mjw@1654 | 33 msg message |
mjw@1654 | 34 type major message type |
mjw@1654 | 35 subtype minor message type |
mjw@1654 | 36 """ |
mjw@1623 | 37 method = self.subTypes.get(subtype) |
mjw@1623 | 38 if method: |
mjw@1623 | 39 method(msg, 1) |
mjw@1623 | 40 else: |
mjw@1623 | 41 print ('requestReceived> No handler: Message type %s %d:%d' |
mjw@1623 | 42 % (msgTypeName(type, subtype), type, subtype)), self |
mjw@1623 | 43 |
mjw@1623 | 44 def responseReceived(self, msg, type, subtype): |
mjw@1654 | 45 """Dispatch a response to handlers. |
mjw@1654 | 46 |
mjw@1654 | 47 msg message |
mjw@1654 | 48 type major message type |
mjw@1654 | 49 subtype minor message type |
mjw@1654 | 50 """ |
mjw@1623 | 51 method = self.subTypes.get(subtype) |
mjw@1623 | 52 if method: |
mjw@1623 | 53 method(msg, 0) |
mjw@1623 | 54 else: |
mjw@1623 | 55 print ('responseReceived> No handler: Message type %s %d:%d' |
mjw@1623 | 56 % (msgTypeName(type, subtype), type, subtype)), self |
mjw@1623 | 57 |
mjw@1623 | 58 def lostChannel(self): |
mjw@1654 | 59 """Called when the channel to the domain is lost. |
mjw@1654 | 60 """ |
mjw@1623 | 61 pass |
mjw@1623 | 62 |
mjw@1623 | 63 def registerChannel(self): |
mjw@1654 | 64 """Register interest in our major message types with the |
mjw@1654 | 65 channel to our domain. |
mjw@1654 | 66 """ |
mjw@1623 | 67 #print 'CtrlMsgRcvr>registerChannel>', self |
mjw@1623 | 68 self.channel = self.channelFactory.domChannel(self.dom) |
mjw@1623 | 69 self.idx = self.channel.getIndex() |
mjw@1623 | 70 if self.majorTypes: |
mjw@1623 | 71 self.channel.registerDevice(self.majorTypes, self) |
mjw@1623 | 72 |
mjw@1623 | 73 def deregisterChannel(self): |
mjw@1654 | 74 """Deregister interest in our major message types with the |
mjw@1654 | 75 channel to our domain. |
mjw@1654 | 76 """ |
mjw@1623 | 77 #print 'CtrlMsgRcvr>deregisterChannel>', self |
mjw@1623 | 78 if self.channel: |
mjw@1623 | 79 self.channel.deregisterDevice(self) |
mjw@1623 | 80 del self.channel |
mjw@1623 | 81 |
mjw@1623 | 82 def produceRequests(self): |
mjw@1654 | 83 """Produce any queued requests. |
mjw@1654 | 84 |
mjw@1654 | 85 return number produced |
mjw@1654 | 86 """ |
mjw@1623 | 87 return 0 |
mjw@1623 | 88 |
mjw@1623 | 89 def writeRequest(self, msg): |
mjw@1654 | 90 """Write a request to the channel. |
mjw@1654 | 91 """ |
mjw@1623 | 92 if self.channel: |
mjw@1623 | 93 self.channel.writeRequest(msg) |
mjw@1623 | 94 else: |
mjw@1623 | 95 print 'CtrlMsgRcvr>writeRequest>', 'no channel!', self |
mjw@1623 | 96 |
mjw@1623 | 97 def writeResponse(self, msg): |
mjw@1654 | 98 """Write a response to the channel. |
mjw@1654 | 99 """ |
mjw@1623 | 100 if self.channel: |
mjw@1623 | 101 self.channel.writeResponse(msg) |
mjw@1623 | 102 else: |
mjw@1623 | 103 print 'CtrlMsgRcvr>writeResponse>', 'no channel!', self |
mjw@1623 | 104 |
mjw@1623 | 105 class ControllerFactory(CtrlMsgRcvr): |
mjw@1623 | 106 """Abstract class for factories creating controllers. |
mjw@1623 | 107 Maintains a table of instances. |
mjw@1654 | 108 |
mjw@1654 | 109 Instance variables: |
mjw@1654 | 110 |
mjw@1654 | 111 instances : mapping of index to controller instance |
mjw@1654 | 112 dlist : list of deferreds |
mjw@1654 | 113 dom : domain |
mjw@1654 | 114 timeout : deferred timeout |
mjw@1623 | 115 """ |
mjw@1623 | 116 |
mjw@1623 | 117 def __init__(self): |
mjw@1623 | 118 CtrlMsgRcvr.__init__(self) |
mjw@1623 | 119 self.instances = {} |
mjw@1623 | 120 self.dlist = [] |
mjw@1623 | 121 self.dom = 0 |
mjw@1623 | 122 # Timeout (in seconds) for deferreds. |
mjw@1623 | 123 self.timeout = 10 |
mjw@1623 | 124 |
mjw@1623 | 125 def addInstance(self, instance): |
mjw@1654 | 126 """Add a controller instance (under its index). |
mjw@1654 | 127 """ |
mjw@1623 | 128 self.instances[instance.idx] = instance |
mjw@1623 | 129 |
mjw@1623 | 130 def getInstance(self, idx): |
mjw@1654 | 131 """Get a controller instance from its index. |
mjw@1654 | 132 """ |
mjw@1623 | 133 return self.instances.get(idx) |
mjw@1623 | 134 |
mjw@1623 | 135 def getInstances(self): |
mjw@1654 | 136 """Get a list of all controller instances. |
mjw@1654 | 137 """ |
mjw@1623 | 138 return self.instances.values() |
mjw@1623 | 139 |
mjw@1623 | 140 def getInstanceByDom(self, dom): |
mjw@1654 | 141 """Get the controller instance for the given domain. |
mjw@1654 | 142 """ |
mjw@1623 | 143 for inst in self.instances.values(): |
mjw@1623 | 144 if inst.dom == dom: |
mjw@1623 | 145 return inst |
mjw@1623 | 146 return None |
mjw@1623 | 147 |
mjw@1623 | 148 def delInstance(self, instance): |
mjw@1654 | 149 """Delete an instance from the table. |
mjw@1654 | 150 """ |
mjw@1623 | 151 if instance.idx in self.instances: |
mjw@1623 | 152 del self.instances[instance.idx] |
mjw@1623 | 153 |
mjw@1623 | 154 def createInstance(self, dom, recreate=0): |
mjw@1654 | 155 """Create an instance. Define in a subclass. |
mjw@1654 | 156 """ |
mjw@1623 | 157 raise NotImplementedError() |
mjw@1623 | 158 |
mjw@1623 | 159 def instanceClosed(self, instance): |
mjw@1654 | 160 """Callback called when an instance is closed (usually by the instance). |
mjw@1654 | 161 """ |
mjw@1623 | 162 self.delInstance(instance) |
mjw@1623 | 163 |
mjw@1623 | 164 def addDeferred(self): |
mjw@1654 | 165 """Add a deferred object. |
mjw@1654 | 166 |
mjw@1654 | 167 returns deferred |
mjw@1654 | 168 """ |
mjw@1623 | 169 d = defer.Deferred() |
mjw@1623 | 170 if self.timeout > 0: |
mjw@1623 | 171 # The deferred will error if not called before timeout. |
mjw@1623 | 172 d.setTimeout(self.timeout) |
mjw@1623 | 173 self.dlist.append(d) |
mjw@1623 | 174 return d |
mjw@1623 | 175 |
mjw@1623 | 176 def callDeferred(self, *args): |
mjw@1654 | 177 """Call the top deferred object |
mjw@1654 | 178 |
mjw@1654 | 179 args arguments |
mjw@1654 | 180 """ |
mjw@1623 | 181 if self.dlist: |
mjw@1623 | 182 d = self.dlist.pop(0) |
mjw@1623 | 183 d.callback(*args) |
mjw@1623 | 184 |
mjw@1623 | 185 def errDeferred(self, *args): |
mjw@1654 | 186 """Signal an error to the top deferred object. |
mjw@1654 | 187 |
mjw@1654 | 188 args arguments |
mjw@1654 | 189 """ |
mjw@1623 | 190 if self.dlist: |
mjw@1623 | 191 d = self.dlist.pop(0) |
mjw@1623 | 192 d.errback(*args) |
mjw@1623 | 193 |
mjw@1623 | 194 class Controller(CtrlMsgRcvr): |
mjw@1623 | 195 """Abstract class for a device controller attached to a domain. |
mjw@1623 | 196 """ |
mjw@1623 | 197 |
mjw@1623 | 198 def __init__(self, factory, dom): |
mjw@1623 | 199 CtrlMsgRcvr.__init__(self) |
mjw@1623 | 200 self.factory = factory |
mjw@1623 | 201 self.dom = int(dom) |
mjw@1623 | 202 self.channel = None |
mjw@1623 | 203 self.idx = None |
mjw@1623 | 204 |
mjw@1623 | 205 def close(self): |
mjw@1654 | 206 """Close the controller. |
mjw@1654 | 207 """ |
mjw@1623 | 208 self.deregisterChannel() |
mjw@1623 | 209 self.lostChannel() |
mjw@1623 | 210 |
mjw@1623 | 211 def lostChannel(self): |
mjw@1654 | 212 """The controller channel has been lost. |
mjw@1654 | 213 """ |
mjw@1623 | 214 self.factory.instanceClosed(self) |
mjw@1623 | 215 |
mjw@1623 | 216 class Dev: |
mjw@1654 | 217 """Abstract class for a device attached to a device controller. |
mjw@1654 | 218 """ |
mjw@1654 | 219 |
mjw@1623 | 220 def __init__(self, controller): |
mjw@1623 | 221 self.controller = controller |
mjw@1623 | 222 self.props = {} |
mjw@1623 | 223 |
mjw@1623 | 224 def setprop(self, k, v): |
mjw@1623 | 225 self.props[k] = v |
mjw@1623 | 226 |
mjw@1623 | 227 def getprop(self, k, v=None): |
mjw@1623 | 228 return self.props.get(k, v) |
mjw@1623 | 229 |
mjw@1623 | 230 def hasprop(self, k): |
mjw@1623 | 231 return k in self.props |
mjw@1623 | 232 |
mjw@1623 | 233 def delprop(self, k): |
mjw@1623 | 234 if k in self.props: |
mjw@1623 | 235 del self.props[k] |
mjw@1623 | 236 |
mjw@1623 | 237 def sxpr(self): |
mjw@1623 | 238 raise NotImplementedError() |
mjw@1623 | 239 |
mjw@1623 | 240 |