1# _entity.py 2# 3# openipmi GUI handling for entities 4# 5# Author: MontaVista Software, Inc. 6# Corey Minyard <minyard@mvista.com> 7# source@mvista.com 8# 9# Copyright 2005 MontaVista Software Inc. 10# 11# This program is free software; you can redistribute it and/or 12# modify it under the terms of the GNU Lesser General Public License 13# as published by the Free Software Foundation; either version 2 of 14# the License, or (at your option) any later version. 15# 16# 17# THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED 18# WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 19# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 20# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 21# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 22# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS 23# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 24# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR 25# TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE 26# USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27# 28# You should have received a copy of the GNU Lesser General Public 29# License along with this program; if not, write to the Free 30# Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 31# 32 33import OpenIPMI 34from openipmigui import _oi_logging 35from openipmigui import _sensor 36from openipmigui import _control 37from openipmigui import _fru 38from openipmigui import gui_popup 39from openipmigui import gui_setdialog 40 41class EntityOp: 42 def __init__(self, e, func): 43 self.e = e 44 self.func = func 45 return 46 47 def DoOp(self): 48 rv = self.e.entity_id.to_entity(self) 49 if (rv == 0): 50 rv = self.rv 51 pass 52 return rv; 53 54 def entity_cb(self, entity): 55 self.rv = getattr(entity, self.func)(self.e) 56 return 57 58 pass 59 60class EntityFruViewer: 61 def __init__(self, e): 62 self.e = e 63 self.e.entity_id.to_entity(self) 64 return 65 66 def entity_cb(self, entity): 67 fru = entity.get_fru() 68 if (fru == None): 69 return 70 _fru.FruInfoDisplay(fru, str(self.e)) 71 return 72 73 pass 74 75class ActivationTimeSetter: 76 def __init__(self, e, name, func): 77 self.e = e 78 self.name = name 79 self.func = func 80 81 self.err = 0 82 rv = e.entity_id.to_entity(self) 83 if (rv == 0): 84 rv = self.err 85 pass 86 if (rv): 87 _oi_logging.error("Error doing entity cb in activation time setter: " 88 + str(rv)) 89 pass 90 91 return 92 93 def ok(self, val): 94 self.acttime = int(val) 95 rv = self.e.entity_id.to_entity(self) 96 if (rv == 0): 97 rv = self.err 98 pass 99 if (rv != 0): 100 return ("Error setting activation time: " 101 + OpenIPMI.get_error_string(rv)) 102 return 103 104 def entity_cb(self, entity): 105 if (self.setting): 106 self.err = getattr(entity, 'set_' + self.func)(None) 107 else: 108 self.err = getattr(entity, 'get_' + self.func)(self) 109 pass 110 return 111 112 def entity_hot_swap_get_time_cb(self, entity, err, time): 113 if (err): 114 _oi_logging.error("Error getting activation time: " + str(err)) 115 return 116 gui_setdialog.SetDialog("Set " + self.name + " for " + str(self.e), 117 [ time ], 118 1, 119 self) 120 return 121 122 pass 123 124class Entity: 125 def __init__(self, d, entity): 126 self.d = d 127 self.ui = d.ui 128 self.name = entity.get_name() 129 self.entity_id = entity.get_id() 130 self.entity_id_str = entity.get_entity_id_string() 131 self.sensors = { } 132 self.controls = { } 133 self.children = { } 134 entity.add_presence_handler(self) 135 entity.add_hot_swap_handler(self) 136 entity.add_sensor_update_handler(self) 137 entity.add_control_update_handler(self) 138 139 d.entities[self.name] = self 140 141 self.destroyed = False 142 143 # Find my parent and put myself in that hierarchy 144 self.parent_id = None 145 self.parent = None 146 self.eeop = "fparent" 147 entity.iterate_parents(self) 148 self.ui.add_entity(self.d, self, parent=self.parent) 149 if (self.parent != None): 150 self.parent.children[self.name] = self.name 151 self.parent_name = self.parent.name 152 pass 153 else: 154 self.parent_name = None 155 pass 156 self.parent = None # Don't leave circular reference 157 158 self.hot_swap = 'No' 159 self.hot_swap_state = '' 160 self.create_my_items() 161 162 self.Changed(entity) 163 return 164 165 def create_my_items(self): 166 self.ui.append_item(self, 'Entity ID', self.entity_id_str) 167 self.typeitem = self.ui.append_item(self, 'Type', None) 168 self.idstringitem = self.ui.append_item(self, 'ID String', None) 169 self.psatitem = self.ui.append_item(self, 170 'Presence Sensor Always There', 171 None) 172 self.slotnumitem = self.ui.append_item(self, 'Slot Number', None) 173 self.mcitem = self.ui.append_item(self, 'MC', None) 174 self.hotswapitem = self.ui.append_item(self, 'Hot Swap', self.hot_swap) 175 return 176 177 def __str__(self): 178 return self.name 179 180 def HandleMenu(self, event): 181 if (self.impt_data == None): 182 menul = [ [ "Add to watch values", self.add_impt ] ] 183 pass 184 else: 185 menul = [ [ "Remove from watch values", self.remove_impt ] ] 186 pass 187 if (self.is_fru): 188 menul.append(["View FRU Data", self.ViewFruData]) 189 pass 190 191 if (self.hot_swap == "Managed"): 192 menul.append(["Request Activation", self.RequestActivation]) 193 menul.append(["Activate", self.Activate]) 194 menul.append(["Deactivate", self.Deactivate]) 195 if (self.supports_auto_activate): 196 menul.append(["Set Auto-activate Time", self.SetAutoActTime]) 197 pass 198 if (self.supports_auto_deactivate): 199 menul.append(["Set Auto-deactivate Time", 200 self.SetAutoDeactTime]) 201 pass 202 pass 203 204 if (len(menul) > 0): 205 gui_popup.popup(self.d.ui, event, menul) 206 pass 207 return 208 209 def add_impt(self, event): 210 self.ui.add_impt_data("entity", str(self), self) 211 return 212 213 def remove_impt(self, event): 214 self.ui.remove_impt_data(self.impt_data) 215 return 216 217 def RequestActivation(self, event): 218 oper = EntityOp(self, "set_activation_requested") 219 rv = oper.DoOp() 220 if (rv != 0): 221 _oi_logging.error("entity set activation failed: " + str(rv)) 222 pass 223 return 224 225 def Activate(self, event): 226 oper = EntityOp(self, "activate") 227 rv = oper.DoOp() 228 if (rv != 0): 229 _oi_logging.error("entity activation failed: " + str(rv)) 230 pass 231 return 232 233 def Deactivate(self, event): 234 oper = EntityOp(self, "deactivate") 235 rv = oper.DoOp() 236 if (rv != 0): 237 _oi_logging.error("entity deactivation failed: " + str(rv)) 238 pass 239 return 240 241 def SetAutoActTime(self, event): 242 ActivationTimeSetter(self, "Activation Time", "auto_activate_time") 243 return 244 245 def SetAutoDeactTime(self, event): 246 ActivationTimeSetter(self, "Deactivation Time", "auto_deactivate_time") 247 return 248 249 def ViewFruData(self, event): 250 EntityFruViewer(self) 251 return 252 253 def entity_activate_cb(self, entity, err): 254 if (err != 0): 255 _oi_logging.error("entity activate operation failed: " + str(err)) 256 pass 257 return 258 259 def Changed(self, entity): 260 # Reparent first, in case parent has changed. 261 old_parent_id = self.parent_id 262 reparent = False 263 self.parent_id = None 264 self.parent = None 265 self.eeop = "fparent" 266 entity.iterate_parents(self) 267 if (self.parent_id != None): 268 if (old_parent_id == None): 269 reparent = True 270 pass 271 elif (self.parent_id.cmp(old_parent_id) != 0): 272 reparent = True 273 pass 274 pass 275 else: 276 if (old_parent_id != None): 277 reparent = True 278 pass 279 pass 280 281 if (reparent): 282 old_treeroot = self.treeroot 283 self.eop = "deleted" 284 entity.iterate_sensors(self) 285 entity.iterate_controls(self) 286 287 if (self.parent_name): 288 oparent = self.d.find_entity_byname(self.parent_name) 289 if (oparent): 290 del oparent.children[self.name] 291 pass 292 self.ui.reparent_entity(self.d, self, self.parent) 293 if (self.parent != None): 294 self.parent.children[self.name] = self.name 295 self.parent_name = self.parent.name 296 pass 297 else: 298 self.parent_name = None 299 pass 300 self.create_my_items() 301 302 # Reparent children 303 self.eeop = "repch" 304 entity.iterate_children(self); 305 306 self.eop = "added" 307 entity.iterate_sensors(self) 308 entity.iterate_controls(self) 309 310 if (entity.is_present()): 311 self.ui.set_item_active(self.treeroot); 312 pass 313 else: 314 self.ui.set_item_inactive(self.treeroot); 315 pass 316 317 self.eop = None 318 self.ui.remove_entity(old_treeroot) 319 pass 320 321 self.parent = None # Kill circular reference 322 323 324 self.is_fru = entity.is_fru() 325 326 self.id_str = entity.get_id_string() 327 eid = self.id_str 328 if (eid == None): 329 eid = self.entity_id_str 330 pass 331 if (eid != None): 332 self.ui.set_item_text(self.treeroot, eid) 333 pass 334 335 self.entity_type = entity.get_type() 336 self.slot_number = entity.get_physical_slot_num() 337 if (self.slot_number < 0): 338 self.slot_number = None 339 pass 340 341 self.mc_id = entity.get_mc_id() 342 self.mc_name = None 343 if (self.mc_id != None): 344 self.mc_id.to_mc(self); 345 pass 346 347 if entity.is_hot_swappable(): 348 if entity.supports_managed_hot_swap(): 349 hot_swap = "Managed" 350 else: 351 hot_swap = "Simple" 352 pass 353 else: 354 hot_swap = "No" 355 pass 356 if (hot_swap != self.hot_swap): 357 self.hot_swap = hot_swap 358 if (hot_swap != "No"): 359 entity.get_hot_swap_state(self) 360 else: 361 self.hot_swap_state = '' 362 pass 363 pass 364 365 self.supports_auto_activate = entity.supports_auto_activate_time() 366 self.supports_auto_deactivate = entity.supports_auto_deactivate_time() 367 368 # Fill in the various value in the GUI 369 self.ui.set_item_text(self.typeitem, self.entity_type) 370 self.ui.set_item_text(self.idstringitem, self.id_str) 371 self.ui.set_item_text(self.psatitem, 372 str(entity.get_presence_sensor_always_there() != 0)) 373 if (self.slot_number != None): 374 self.ui.set_item_text(self.slotnumitem, str(self.slot_number)) 375 pass 376 self.ui.set_item_text(self.mcitem, self.mc_name) 377 self.ui.set_item_text(self.hotswapitem, 378 self.hot_swap + ' ' + self.hot_swap_state) 379 return 380 381 def entity_hot_swap_update_cb(self, entity, old_state, new_state, event): 382 if (self.destroyed): 383 return 384 self.hot_swap_state = new_state 385 self.ui.set_item_text(self.hotswapitem, 386 self.hot_swap + ' ' + self.hot_swap_state) 387 return OpenIPMI.EVENT_NOT_HANDLED 388 389 def entity_hot_swap_cb(self, entity, err, state): 390 if (self.destroyed): 391 return 392 if (err): 393 _oi_logging.error("Error getting entity hot-swap state: " + str(err)) 394 return 395 self.hot_swap_state = state 396 self.ui.set_item_text(self.hotswapitem, 397 self.hot_swap + ' ' + self.hot_swap_state) 398 return 399 400 def mc_cb(self, mc): 401 self.mc_name = mc.get_name() 402 return 403 404 def entity_iter_entities_cb(self, e1, e2): 405 if (self.eeop == "fparent"): 406 self.parent_id = e2.get_id() 407 self.parent = self.d.find_or_create_entity(e2) 408 pass 409 elif (self.eeop == "repch"): 410 ch_e = self.d.find_entity_byname(e2.get_name()) 411 if (ch_e): 412 ch_e.parent_id = None 413 ch_e.Changed(e2) 414 pass 415 pass 416 return 417 418 def entity_iter_sensors_cb(self, entity, sensor): 419 self.entity_sensor_update_cb(self.eop, entity, sensor) 420 return 421 422 def entity_iter_controls_cb(self, entity, control): 423 self.entity_control_update_cb(self.eop, entity, control) 424 return 425 426 def remove(self): 427 self.d.entities.pop(self.name) 428 self.ui.remove_entity(self) 429 self.destroyed = True 430 self.d = None 431 self.ui = None 432 return 433 434 def entity_sensor_update_cb(self, op, entity, sensor): 435 if (self.destroyed): 436 return 437 if (op == "added"): 438 if (sensor.get_name() not in self.sensors): 439 e = _sensor.Sensor(self, sensor) 440 pass 441 pass 442 elif (op == "deleted"): 443 if (sensor.get_name() in self.sensors): 444 self.sensors[sensor.get_name()].remove() 445 pass 446 pass 447 return 448 449 def entity_control_update_cb(self, op, entity, control): 450 if (self.destroyed): 451 return 452 if (op == "added"): 453 if (control.get_name() not in self.controls): 454 e = _control.Control(self, control) 455 pass 456 pass 457 elif (op == "deleted"): 458 if (control.get_name() in self.controls): 459 self.controls[control.get_name()].remove() 460 pass 461 pass 462 return 463 464 def entity_presence_cb(self, entity, present, event): 465 if (self.destroyed): 466 return 467 if (present): 468 self.ui.set_item_active(self.treeroot) 469 else: 470 self.ui.set_item_inactive(self.treeroot) 471 pass 472 return 473 474 def entity_fru_update_werr_cb(self, op, err, entity, fru): 475 if (self.destroyed): 476 return 477 if (op == "error"): 478 _oi_logging.error("Error getting entity fru: " + str(err)) 479 return 480 481 pass 482