blob: b5528c8ab4e2006db7e1318d51518068ad9e1a76 [file] [log] [blame]
Brad Bishop87c6b732016-08-30 19:17:57 -04001#!/usr/bin/env python
Norman Jamese2765102015-08-19 22:00:55 -05002
CamVan Nguyend65b2d52018-02-27 15:14:41 -06003# TODO: openbmc/openbmc#2994 remove python 2 support
4try: # python 2
5 import gobject
6except ImportError: # python 3
7 from gi.repository import GObject as gobject
Norman Jamese2765102015-08-19 22:00:55 -05008import dbus
9import dbus.service
10import dbus.mainloop.glib
Brad Bishop84e73b52016-05-12 15:57:52 -040011from obmc.dbuslib.bindings import get_dbus, DbusProperties, DbusObjectManager
Norman Jamese2765102015-08-19 22:00:55 -050012
Patrick Williams75fe8cc2022-07-22 16:12:12 -050013DBUS_NAME = "org.openbmc.control.Chassis"
14OBJ_NAME = "/org/openbmc/control/chassis0"
15CONTROL_INTF = "org.openbmc.Control"
Norman James3f97c5d2015-08-26 17:44:14 -050016
Patrick Williams75fe8cc2022-07-22 16:12:12 -050017MACHINE_ID = "/etc/machine-id"
Norman Jamesad8c3d32016-02-11 15:19:01 -060018
Norman James2a3d20b2015-08-20 07:09:33 -050019POWER_OFF = 0
20POWER_ON = 1
21
Norman James9e6acf92015-09-08 07:00:04 -050022BOOTED = 100
23
Norman James90baede2015-09-02 20:32:49 -050024
Andrew Geisslerb7f40b52016-06-29 15:49:26 -050025class ChassisControlObject(DbusProperties, DbusObjectManager):
26 def getUuid(self):
Brad Bishop7a4d77a2016-09-08 23:26:17 -040027 uuid = ""
Andrew Geisslerb7f40b52016-06-29 15:49:26 -050028 try:
29 with open(MACHINE_ID) as f:
Patrick Williams75fe8cc2022-07-22 16:12:12 -050030 data = f.readline().rstrip("\n")
31 if len(data) == 32:
Andrew Geisslerb7f40b52016-06-29 15:49:26 -050032 uuid = data
33 else:
CamVan Nguyend65b2d52018-02-27 15:14:41 -060034 print("ERROR: UUID is not formatted correctly: " + data)
Adriana Kobylak24341f92018-01-26 15:07:23 -060035 except Exception:
CamVan Nguyend65b2d52018-02-27 15:14:41 -060036 print("ERROR: Unable to open uuid file: " + MACHINE_ID)
Adriana Kobylak08d3bdb2015-10-20 16:59:14 -050037
Andrew Geisslerb7f40b52016-06-29 15:49:26 -050038 return uuid
Norman Jamescfc2b442015-10-31 17:31:46 -050039
Andrew Geisslerb7f40b52016-06-29 15:49:26 -050040 def __init__(self, bus, name):
Patrick Williams75fe8cc2022-07-22 16:12:12 -050041 super(ChassisControlObject, self).__init__(conn=bus, object_path=name)
Adriana Kobylak24341f92018-01-26 15:07:23 -060042 # load utilized objects
Andrew Geisslerb7f40b52016-06-29 15:49:26 -050043 self.dbus_objects = {
Patrick Williams75fe8cc2022-07-22 16:12:12 -050044 "power_control": {
45 "bus_name": "org.openbmc.control.Power",
46 "object_name": "/org/openbmc/control/power0",
47 "interface_name": "org.openbmc.control.Power",
Andrew Geisslerb7f40b52016-06-29 15:49:26 -050048 },
Patrick Williams75fe8cc2022-07-22 16:12:12 -050049 "host_services": {
50 "bus_name": "org.openbmc.HostServices",
51 "object_name": "/org/openbmc/HostServices",
52 "interface_name": "org.openbmc.HostServices",
Andrew Geisslerb7f40b52016-06-29 15:49:26 -050053 },
Patrick Williams75fe8cc2022-07-22 16:12:12 -050054 "systemd": {
55 "bus_name": "org.freedesktop.systemd1",
56 "object_name": "/org/freedesktop/systemd1",
57 "interface_name": "org.freedesktop.systemd1.Manager",
Andrew Geissler6b63e9a2016-06-30 10:45:01 -050058 },
Andrew Geisslerb7f40b52016-06-29 15:49:26 -050059 }
Norman James72567ba2016-01-13 16:57:48 -060060
Andrew Geisslerb7f40b52016-06-29 15:49:26 -050061 # uuid
62 self.Set(DBUS_NAME, "uuid", self.getUuid())
63 self.Set(DBUS_NAME, "reboot", 0)
Norman James72567ba2016-01-13 16:57:48 -060064
Patrick Williams75fe8cc2022-07-22 16:12:12 -050065 bus.add_signal_receiver(
66 self.power_button_signal_handler,
67 dbus_interface="org.openbmc.Button",
68 signal_name="Released",
69 path="/org/openbmc/buttons/power0",
70 )
71 bus.add_signal_receiver(
72 self.long_power_button_signal_handler,
73 dbus_interface="org.openbmc.Button",
74 signal_name="PressedLong",
75 path="/org/openbmc/buttons/power0",
76 )
77 bus.add_signal_receiver(
78 self.softreset_button_signal_handler,
79 dbus_interface="org.openbmc.Button",
80 signal_name="Released",
81 path="/org/openbmc/buttons/reset0",
82 )
Andrew Geisslerb7f40b52016-06-29 15:49:26 -050083
Patrick Williams75fe8cc2022-07-22 16:12:12 -050084 bus.add_signal_receiver(
85 self.host_watchdog_signal_handler,
86 dbus_interface="org.openbmc.Watchdog",
87 signal_name="WatchdogError",
88 )
Norman James471ab592015-08-30 22:29:40 -050089
Andrew Geisslerb7f40b52016-06-29 15:49:26 -050090 def getInterface(self, name):
91 o = self.dbus_objects[name]
Patrick Williams75fe8cc2022-07-22 16:12:12 -050092 obj = bus.get_object(o["bus_name"], o["object_name"], introspect=False)
93 return dbus.Interface(obj, o["interface_name"])
Norman Jamese2765102015-08-19 22:00:55 -050094
Patrick Williams75fe8cc2022-07-22 16:12:12 -050095 @dbus.service.method(DBUS_NAME, in_signature="", out_signature="")
Andrew Geisslerb7f40b52016-06-29 15:49:26 -050096 def powerOn(self):
CamVan Nguyend65b2d52018-02-27 15:14:41 -060097 print("Turn on power and boot")
Andrew Geisslerb7f40b52016-06-29 15:49:26 -050098 self.Set(DBUS_NAME, "reboot", 0)
Patrick Williams75fe8cc2022-07-22 16:12:12 -050099 intf = self.getInterface("systemd")
100 f = getattr(intf, "StartUnit")
101 f.call_async("obmc-host-start@0.target", "replace")
Andrew Geisslerb7f40b52016-06-29 15:49:26 -0500102 return None
Norman Jamese2765102015-08-19 22:00:55 -0500103
Patrick Williams75fe8cc2022-07-22 16:12:12 -0500104 @dbus.service.method(DBUS_NAME, in_signature="", out_signature="")
Andrew Geisslerb7f40b52016-06-29 15:49:26 -0500105 def powerOff(self):
CamVan Nguyend65b2d52018-02-27 15:14:41 -0600106 print("Turn off power")
Patrick Williams75fe8cc2022-07-22 16:12:12 -0500107 intf = self.getInterface("systemd")
108 f = getattr(intf, "StartUnit")
109 f.call_async("obmc-chassis-hard-poweroff@0.target", "replace")
Andrew Geisslerb7f40b52016-06-29 15:49:26 -0500110 return None
Norman James362a80f2015-09-14 14:04:39 -0500111
Patrick Williams75fe8cc2022-07-22 16:12:12 -0500112 @dbus.service.method(DBUS_NAME, in_signature="", out_signature="")
Andrew Geisslerb7f40b52016-06-29 15:49:26 -0500113 def softPowerOff(self):
CamVan Nguyend65b2d52018-02-27 15:14:41 -0600114 print("Soft off power")
Patrick Williams75fe8cc2022-07-22 16:12:12 -0500115 intf = self.getInterface("systemd")
116 f = getattr(intf, "StartUnit")
117 f.call_async("obmc-host-shutdown@0.target", "replace")
Andrew Geisslerb7f40b52016-06-29 15:49:26 -0500118 return None
Norman James362a80f2015-09-14 14:04:39 -0500119
Patrick Williams75fe8cc2022-07-22 16:12:12 -0500120 @dbus.service.method(DBUS_NAME, in_signature="", out_signature="")
Andrew Geisslerb7f40b52016-06-29 15:49:26 -0500121 def reboot(self):
CamVan Nguyend65b2d52018-02-27 15:14:41 -0600122 print("Rebooting")
Alexander Soldatove32e3372018-10-31 14:29:31 +0300123 if self.getPowerState() != POWER_OFF:
Andrew Geisslerb7f40b52016-06-29 15:49:26 -0500124 self.Set(DBUS_NAME, "reboot", 1)
125 self.powerOff()
126 return None
Norman Jamesb4ef3182015-12-03 17:54:35 -0600127
Patrick Williams75fe8cc2022-07-22 16:12:12 -0500128 @dbus.service.method(DBUS_NAME, in_signature="", out_signature="")
Andrew Geisslerb7f40b52016-06-29 15:49:26 -0500129 def softReboot(self):
CamVan Nguyend65b2d52018-02-27 15:14:41 -0600130 print("Soft Rebooting")
Alexander Soldatove32e3372018-10-31 14:29:31 +0300131 if self.getPowerState() != POWER_OFF:
Andrew Geisslerb7f40b52016-06-29 15:49:26 -0500132 self.Set(DBUS_NAME, "reboot", 1)
133 self.softPowerOff()
134 return None
Norman Jamese2765102015-08-19 22:00:55 -0500135
Patrick Williams75fe8cc2022-07-22 16:12:12 -0500136 @dbus.service.method(DBUS_NAME, in_signature="", out_signature="")
Michael Tritz6d2f6c32017-02-02 17:03:18 -0600137 def quiesce(self):
Patrick Williams75fe8cc2022-07-22 16:12:12 -0500138 intf = self.getInterface("systemd")
139 f = getattr(intf, "StartUnit")
140 f.call_async("obmc-host-quiesce@0.target", "replace")
Michael Tritz6d2f6c32017-02-02 17:03:18 -0600141 return None
142
Patrick Williams75fe8cc2022-07-22 16:12:12 -0500143 @dbus.service.method(DBUS_NAME, in_signature="", out_signature="i")
Andrew Geisslerb7f40b52016-06-29 15:49:26 -0500144 def getPowerState(self):
Patrick Williams75fe8cc2022-07-22 16:12:12 -0500145 intf = self.getInterface("power_control")
Andrew Geisslerb7f40b52016-06-29 15:49:26 -0500146 return intf.getPowerState()
Norman Jamese2765102015-08-19 22:00:55 -0500147
Adriana Kobylak24341f92018-01-26 15:07:23 -0600148 # Signal handler
Norman James362a80f2015-09-14 14:04:39 -0500149
Andrew Geisslerb7f40b52016-06-29 15:49:26 -0500150 def power_button_signal_handler(self):
Adriana Kobylakeeb9b442016-08-15 11:12:53 -0500151 # toggle power, power-on / soft-power-off
Andrew Geisslerb7f40b52016-06-29 15:49:26 -0500152 state = self.getPowerState()
153 if state == POWER_OFF:
154 self.powerOn()
155 elif state == POWER_ON:
Brad Bishop7a4d77a2016-09-08 23:26:17 -0400156 self.softPowerOff()
Norman Jamese2765102015-08-19 22:00:55 -0500157
Adriana Kobylakeeb9b442016-08-15 11:12:53 -0500158 def long_power_button_signal_handler(self):
CamVan Nguyend65b2d52018-02-27 15:14:41 -0600159 print("Long-press button, hard power off")
Brad Bishop7a4d77a2016-09-08 23:26:17 -0400160 self.powerOff()
Kenc95eccd2015-12-19 07:02:34 +0800161
Andrew Geisslerb7f40b52016-06-29 15:49:26 -0500162 def softreset_button_signal_handler(self):
Brad Bishop7a4d77a2016-09-08 23:26:17 -0400163 self.softReboot()
Norman James72567ba2016-01-13 16:57:48 -0600164
Andrew Geisslerb7f40b52016-06-29 15:49:26 -0500165 def host_watchdog_signal_handler(self):
CamVan Nguyend65b2d52018-02-27 15:14:41 -0600166 print("Watchdog Error, Going to quiesce")
Michael Tritz6d2f6c32017-02-02 17:03:18 -0600167 self.quiesce()
Andrew Geisslerb7f40b52016-06-29 15:49:26 -0500168
Norman Jamese2765102015-08-19 22:00:55 -0500169
Patrick Williams75fe8cc2022-07-22 16:12:12 -0500170if __name__ == "__main__":
Norman Jamese2765102015-08-19 22:00:55 -0500171 dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)
172
Brad Bishop84e73b52016-05-12 15:57:52 -0400173 bus = get_dbus()
Norman James3f97c5d2015-08-26 17:44:14 -0500174 obj = ChassisControlObject(bus, OBJ_NAME)
Norman James6f8d0422015-09-14 18:48:00 -0500175 mainloop = gobject.MainLoop()
Brad Bishopf0f3efe2016-06-29 23:20:24 -0400176
177 obj.unmask_signals()
Brad Bishop70852a32016-06-29 22:58:51 -0400178 name = dbus.service.BusName(DBUS_NAME, bus)
Andrew Geisslerb7f40b52016-06-29 15:49:26 -0500179
CamVan Nguyend65b2d52018-02-27 15:14:41 -0600180 print("Running ChassisControlService")
Norman Jamese2765102015-08-19 22:00:55 -0500181 mainloop.run()
Brad Bishop53066752016-09-21 08:48:04 -0400182
183# vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4