1#!/usr/bin/env python 2 3import gobject 4import dbus 5import dbus.service 6import dbus.mainloop.glib 7from obmc.dbuslib.bindings import get_dbus, DbusProperties, DbusObjectManager 8 9DBUS_NAME = 'org.openbmc.control.Chassis' 10OBJ_NAME = '/org/openbmc/control/chassis0' 11CONTROL_INTF = 'org.openbmc.Control' 12 13MACHINE_ID = '/etc/machine-id' 14 15POWER_OFF = 0 16POWER_ON = 1 17 18BOOTED = 100 19 20 21class ChassisControlObject(DbusProperties, DbusObjectManager): 22 def getUuid(self): 23 uuid = "" 24 try: 25 with open(MACHINE_ID) as f: 26 data = f.readline().rstrip('\n') 27 if (len(data) == 32): 28 uuid = data 29 else: 30 print "ERROR: UUID is not formatted correctly: " + data 31 except Exception: 32 print "ERROR: Unable to open uuid file: " + MACHINE_ID 33 34 return uuid 35 36 def __init__(self, bus, name): 37 super(ChassisControlObject, self).__init__( 38 conn=bus, 39 object_path=name) 40 # load utilized objects 41 self.dbus_objects = { 42 'power_control': { 43 'bus_name': 'org.openbmc.control.Power', 44 'object_name': '/org/openbmc/control/power0', 45 'interface_name': 'org.openbmc.control.Power' 46 }, 47 'host_services': { 48 'bus_name': 'org.openbmc.HostServices', 49 'object_name': '/org/openbmc/HostServices', 50 'interface_name': 'org.openbmc.HostServices' 51 }, 52 'systemd': { 53 'bus_name': 'org.freedesktop.systemd1', 54 'object_name': '/org/freedesktop/systemd1', 55 'interface_name': 'org.freedesktop.systemd1.Manager' 56 }, 57 } 58 59 # uuid 60 self.Set(DBUS_NAME, "uuid", self.getUuid()) 61 self.Set(DBUS_NAME, "reboot", 0) 62 63 bus.add_signal_receiver(self.power_button_signal_handler, 64 dbus_interface="org.openbmc.Button", 65 signal_name="Released", 66 path="/org/openbmc/buttons/power0") 67 bus.add_signal_receiver(self.long_power_button_signal_handler, 68 dbus_interface="org.openbmc.Button", 69 signal_name="PressedLong", 70 path="/org/openbmc/buttons/power0") 71 bus.add_signal_receiver(self.softreset_button_signal_handler, 72 dbus_interface="org.openbmc.Button", 73 signal_name="Released", 74 path="/org/openbmc/buttons/reset0") 75 76 bus.add_signal_receiver(self.host_watchdog_signal_handler, 77 dbus_interface="org.openbmc.Watchdog", 78 signal_name="WatchdogError") 79 80 81 def getInterface(self, name): 82 o = self.dbus_objects[name] 83 obj = bus.get_object(o['bus_name'], o['object_name'], introspect=False) 84 return dbus.Interface(obj, o['interface_name']) 85 86 @dbus.service.method(DBUS_NAME, 87 in_signature='', out_signature='') 88 def powerOn(self): 89 print "Turn on power and boot" 90 self.Set(DBUS_NAME, "reboot", 0) 91 intf = self.getInterface('systemd') 92 f = getattr(intf, 'StartUnit') 93 f.call_async('obmc-host-start@0.target', 'replace') 94 return None 95 96 @dbus.service.method(DBUS_NAME, 97 in_signature='', out_signature='') 98 def powerOff(self): 99 print "Turn off power" 100 intf = self.getInterface('systemd') 101 f = getattr(intf, 'StartUnit') 102 f.call_async('obmc-chassis-hard-poweroff@0.target', 'replace') 103 return None 104 105 @dbus.service.method(DBUS_NAME, 106 in_signature='', out_signature='') 107 def softPowerOff(self): 108 print "Soft off power" 109 intf = self.getInterface('systemd') 110 f = getattr(intf, 'StartUnit') 111 f.call_async('obmc-host-shutdown@0.target', 'replace') 112 return None 113 114 @dbus.service.method(DBUS_NAME, 115 in_signature='', out_signature='') 116 def reboot(self): 117 print "Rebooting" 118 if self.getPowerState() == POWER_OFF: 119 self.powerOn() 120 else: 121 self.Set(DBUS_NAME, "reboot", 1) 122 self.powerOff() 123 return None 124 125 @dbus.service.method(DBUS_NAME, 126 in_signature='', out_signature='') 127 def softReboot(self): 128 print "Soft Rebooting" 129 if self.getPowerState() == POWER_OFF: 130 self.powerOn() 131 else: 132 self.Set(DBUS_NAME, "reboot", 1) 133 self.softPowerOff() 134 return None 135 136 @dbus.service.method(DBUS_NAME, 137 in_signature='', out_signature='') 138 def quiesce(self): 139 intf = self.getInterface('systemd') 140 f = getattr(intf, 'StartUnit') 141 f.call_async('obmc-host-quiesce@0.target', 'replace') 142 return None 143 144 @dbus.service.method(DBUS_NAME, 145 in_signature='', out_signature='i') 146 def getPowerState(self): 147 intf = self.getInterface('power_control') 148 return intf.getPowerState() 149 150 # Signal handler 151 152 def power_button_signal_handler(self): 153 # toggle power, power-on / soft-power-off 154 state = self.getPowerState() 155 if state == POWER_OFF: 156 self.powerOn() 157 elif state == POWER_ON: 158 self.softPowerOff() 159 160 def long_power_button_signal_handler(self): 161 print "Long-press button, hard power off" 162 self.powerOff() 163 164 def softreset_button_signal_handler(self): 165 self.softReboot() 166 167 def host_watchdog_signal_handler(self): 168 print "Watchdog Error, Going to quiesce" 169 self.quiesce() 170 171 172if __name__ == '__main__': 173 dbus.mainloop.glib.DBusGMainLoop(set_as_default=True) 174 175 bus = get_dbus() 176 obj = ChassisControlObject(bus, OBJ_NAME) 177 mainloop = gobject.MainLoop() 178 179 obj.unmask_signals() 180 name = dbus.service.BusName(DBUS_NAME, bus) 181 182 print "Running ChassisControlService" 183 mainloop.run() 184 185# vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4 186