blob: efe7227ef2fe77b7837db11d641968f6e0d8df9c [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
Patrick Williamsd8c6f5a2022-12-08 06:18:18 -06008
Norman Jamese2765102015-08-19 22:00:55 -05009import dbus
Norman Jamese2765102015-08-19 22:00:55 -050010import dbus.mainloop.glib
Patrick Williamsd8c6f5a2022-12-08 06:18:18 -060011import dbus.service
12from obmc.dbuslib.bindings import DbusObjectManager, DbusProperties, get_dbus
Norman Jamese2765102015-08-19 22:00:55 -050013
Patrick Williams75fe8cc2022-07-22 16:12:12 -050014DBUS_NAME = "org.openbmc.control.Chassis"
15OBJ_NAME = "/org/openbmc/control/chassis0"
16CONTROL_INTF = "org.openbmc.Control"
Norman James3f97c5d2015-08-26 17:44:14 -050017
Patrick Williams75fe8cc2022-07-22 16:12:12 -050018MACHINE_ID = "/etc/machine-id"
Norman Jamesad8c3d32016-02-11 15:19:01 -060019
Norman James2a3d20b2015-08-20 07:09:33 -050020POWER_OFF = 0
21POWER_ON = 1
22
Norman James9e6acf92015-09-08 07:00:04 -050023BOOTED = 100
24
Norman James90baede2015-09-02 20:32:49 -050025
Andrew Geisslerb7f40b52016-06-29 15:49:26 -050026class ChassisControlObject(DbusProperties, DbusObjectManager):
27 def getUuid(self):
Brad Bishop7a4d77a2016-09-08 23:26:17 -040028 uuid = ""
Andrew Geisslerb7f40b52016-06-29 15:49:26 -050029 try:
30 with open(MACHINE_ID) as f:
Patrick Williams75fe8cc2022-07-22 16:12:12 -050031 data = f.readline().rstrip("\n")
32 if len(data) == 32:
Andrew Geisslerb7f40b52016-06-29 15:49:26 -050033 uuid = data
34 else:
CamVan Nguyend65b2d52018-02-27 15:14:41 -060035 print("ERROR: UUID is not formatted correctly: " + data)
Adriana Kobylak24341f92018-01-26 15:07:23 -060036 except Exception:
CamVan Nguyend65b2d52018-02-27 15:14:41 -060037 print("ERROR: Unable to open uuid file: " + MACHINE_ID)
Adriana Kobylak08d3bdb2015-10-20 16:59:14 -050038
Andrew Geisslerb7f40b52016-06-29 15:49:26 -050039 return uuid
Norman Jamescfc2b442015-10-31 17:31:46 -050040
Andrew Geisslerb7f40b52016-06-29 15:49:26 -050041 def __init__(self, bus, name):
Patrick Williams75fe8cc2022-07-22 16:12:12 -050042 super(ChassisControlObject, self).__init__(conn=bus, object_path=name)
Adriana Kobylak24341f92018-01-26 15:07:23 -060043 # load utilized objects
Andrew Geisslerb7f40b52016-06-29 15:49:26 -050044 self.dbus_objects = {
Patrick Williams75fe8cc2022-07-22 16:12:12 -050045 "power_control": {
46 "bus_name": "org.openbmc.control.Power",
47 "object_name": "/org/openbmc/control/power0",
48 "interface_name": "org.openbmc.control.Power",
Andrew Geisslerb7f40b52016-06-29 15:49:26 -050049 },
Patrick Williams75fe8cc2022-07-22 16:12:12 -050050 "host_services": {
51 "bus_name": "org.openbmc.HostServices",
52 "object_name": "/org/openbmc/HostServices",
53 "interface_name": "org.openbmc.HostServices",
Andrew Geisslerb7f40b52016-06-29 15:49:26 -050054 },
Patrick Williams75fe8cc2022-07-22 16:12:12 -050055 "systemd": {
56 "bus_name": "org.freedesktop.systemd1",
57 "object_name": "/org/freedesktop/systemd1",
58 "interface_name": "org.freedesktop.systemd1.Manager",
Andrew Geissler6b63e9a2016-06-30 10:45:01 -050059 },
Andrew Geisslerb7f40b52016-06-29 15:49:26 -050060 }
Norman James72567ba2016-01-13 16:57:48 -060061
Andrew Geisslerb7f40b52016-06-29 15:49:26 -050062 # uuid
63 self.Set(DBUS_NAME, "uuid", self.getUuid())
64 self.Set(DBUS_NAME, "reboot", 0)
Norman James72567ba2016-01-13 16:57:48 -060065
Patrick Williams75fe8cc2022-07-22 16:12:12 -050066 bus.add_signal_receiver(
67 self.power_button_signal_handler,
68 dbus_interface="org.openbmc.Button",
69 signal_name="Released",
70 path="/org/openbmc/buttons/power0",
71 )
72 bus.add_signal_receiver(
73 self.long_power_button_signal_handler,
74 dbus_interface="org.openbmc.Button",
75 signal_name="PressedLong",
76 path="/org/openbmc/buttons/power0",
77 )
78 bus.add_signal_receiver(
79 self.softreset_button_signal_handler,
80 dbus_interface="org.openbmc.Button",
81 signal_name="Released",
82 path="/org/openbmc/buttons/reset0",
83 )
Andrew Geisslerb7f40b52016-06-29 15:49:26 -050084
Patrick Williams75fe8cc2022-07-22 16:12:12 -050085 bus.add_signal_receiver(
86 self.host_watchdog_signal_handler,
87 dbus_interface="org.openbmc.Watchdog",
88 signal_name="WatchdogError",
89 )
Norman James471ab592015-08-30 22:29:40 -050090
Andrew Geisslerb7f40b52016-06-29 15:49:26 -050091 def getInterface(self, name):
92 o = self.dbus_objects[name]
Patrick Williams75fe8cc2022-07-22 16:12:12 -050093 obj = bus.get_object(o["bus_name"], o["object_name"], introspect=False)
94 return dbus.Interface(obj, o["interface_name"])
Norman Jamese2765102015-08-19 22:00:55 -050095
Patrick Williams75fe8cc2022-07-22 16:12:12 -050096 @dbus.service.method(DBUS_NAME, in_signature="", out_signature="")
Andrew Geisslerb7f40b52016-06-29 15:49:26 -050097 def powerOn(self):
CamVan Nguyend65b2d52018-02-27 15:14:41 -060098 print("Turn on power and boot")
Andrew Geisslerb7f40b52016-06-29 15:49:26 -050099 self.Set(DBUS_NAME, "reboot", 0)
Patrick Williams75fe8cc2022-07-22 16:12:12 -0500100 intf = self.getInterface("systemd")
101 f = getattr(intf, "StartUnit")
102 f.call_async("obmc-host-start@0.target", "replace")
Andrew Geisslerb7f40b52016-06-29 15:49:26 -0500103 return None
Norman Jamese2765102015-08-19 22:00:55 -0500104
Patrick Williams75fe8cc2022-07-22 16:12:12 -0500105 @dbus.service.method(DBUS_NAME, in_signature="", out_signature="")
Andrew Geisslerb7f40b52016-06-29 15:49:26 -0500106 def powerOff(self):
CamVan Nguyend65b2d52018-02-27 15:14:41 -0600107 print("Turn off power")
Patrick Williams75fe8cc2022-07-22 16:12:12 -0500108 intf = self.getInterface("systemd")
109 f = getattr(intf, "StartUnit")
110 f.call_async("obmc-chassis-hard-poweroff@0.target", "replace")
Andrew Geisslerb7f40b52016-06-29 15:49:26 -0500111 return None
Norman James362a80f2015-09-14 14:04:39 -0500112
Patrick Williams75fe8cc2022-07-22 16:12:12 -0500113 @dbus.service.method(DBUS_NAME, in_signature="", out_signature="")
Andrew Geisslerb7f40b52016-06-29 15:49:26 -0500114 def softPowerOff(self):
CamVan Nguyend65b2d52018-02-27 15:14:41 -0600115 print("Soft off power")
Patrick Williams75fe8cc2022-07-22 16:12:12 -0500116 intf = self.getInterface("systemd")
117 f = getattr(intf, "StartUnit")
118 f.call_async("obmc-host-shutdown@0.target", "replace")
Andrew Geisslerb7f40b52016-06-29 15:49:26 -0500119 return None
Norman James362a80f2015-09-14 14:04:39 -0500120
Patrick Williams75fe8cc2022-07-22 16:12:12 -0500121 @dbus.service.method(DBUS_NAME, in_signature="", out_signature="")
Andrew Geisslerb7f40b52016-06-29 15:49:26 -0500122 def reboot(self):
CamVan Nguyend65b2d52018-02-27 15:14:41 -0600123 print("Rebooting")
Alexander Soldatove32e3372018-10-31 14:29:31 +0300124 if self.getPowerState() != POWER_OFF:
Andrew Geisslerb7f40b52016-06-29 15:49:26 -0500125 self.Set(DBUS_NAME, "reboot", 1)
126 self.powerOff()
127 return None
Norman Jamesb4ef3182015-12-03 17:54:35 -0600128
Patrick Williams75fe8cc2022-07-22 16:12:12 -0500129 @dbus.service.method(DBUS_NAME, in_signature="", out_signature="")
Andrew Geisslerb7f40b52016-06-29 15:49:26 -0500130 def softReboot(self):
CamVan Nguyend65b2d52018-02-27 15:14:41 -0600131 print("Soft Rebooting")
Alexander Soldatove32e3372018-10-31 14:29:31 +0300132 if self.getPowerState() != POWER_OFF:
Andrew Geisslerb7f40b52016-06-29 15:49:26 -0500133 self.Set(DBUS_NAME, "reboot", 1)
134 self.softPowerOff()
135 return None
Norman Jamese2765102015-08-19 22:00:55 -0500136
Patrick Williams75fe8cc2022-07-22 16:12:12 -0500137 @dbus.service.method(DBUS_NAME, in_signature="", out_signature="")
Michael Tritz6d2f6c32017-02-02 17:03:18 -0600138 def quiesce(self):
Patrick Williams75fe8cc2022-07-22 16:12:12 -0500139 intf = self.getInterface("systemd")
140 f = getattr(intf, "StartUnit")
141 f.call_async("obmc-host-quiesce@0.target", "replace")
Michael Tritz6d2f6c32017-02-02 17:03:18 -0600142 return None
143
Patrick Williams75fe8cc2022-07-22 16:12:12 -0500144 @dbus.service.method(DBUS_NAME, in_signature="", out_signature="i")
Andrew Geisslerb7f40b52016-06-29 15:49:26 -0500145 def getPowerState(self):
Patrick Williams75fe8cc2022-07-22 16:12:12 -0500146 intf = self.getInterface("power_control")
Andrew Geisslerb7f40b52016-06-29 15:49:26 -0500147 return intf.getPowerState()
Norman Jamese2765102015-08-19 22:00:55 -0500148
Adriana Kobylak24341f92018-01-26 15:07:23 -0600149 # Signal handler
Norman James362a80f2015-09-14 14:04:39 -0500150
Andrew Geisslerb7f40b52016-06-29 15:49:26 -0500151 def power_button_signal_handler(self):
Adriana Kobylakeeb9b442016-08-15 11:12:53 -0500152 # toggle power, power-on / soft-power-off
Andrew Geisslerb7f40b52016-06-29 15:49:26 -0500153 state = self.getPowerState()
154 if state == POWER_OFF:
155 self.powerOn()
156 elif state == POWER_ON:
Brad Bishop7a4d77a2016-09-08 23:26:17 -0400157 self.softPowerOff()
Norman Jamese2765102015-08-19 22:00:55 -0500158
Adriana Kobylakeeb9b442016-08-15 11:12:53 -0500159 def long_power_button_signal_handler(self):
CamVan Nguyend65b2d52018-02-27 15:14:41 -0600160 print("Long-press button, hard power off")
Brad Bishop7a4d77a2016-09-08 23:26:17 -0400161 self.powerOff()
Kenc95eccd2015-12-19 07:02:34 +0800162
Andrew Geisslerb7f40b52016-06-29 15:49:26 -0500163 def softreset_button_signal_handler(self):
Brad Bishop7a4d77a2016-09-08 23:26:17 -0400164 self.softReboot()
Norman James72567ba2016-01-13 16:57:48 -0600165
Andrew Geisslerb7f40b52016-06-29 15:49:26 -0500166 def host_watchdog_signal_handler(self):
CamVan Nguyend65b2d52018-02-27 15:14:41 -0600167 print("Watchdog Error, Going to quiesce")
Michael Tritz6d2f6c32017-02-02 17:03:18 -0600168 self.quiesce()
Andrew Geisslerb7f40b52016-06-29 15:49:26 -0500169
Norman Jamese2765102015-08-19 22:00:55 -0500170
Patrick Williams75fe8cc2022-07-22 16:12:12 -0500171if __name__ == "__main__":
Norman Jamese2765102015-08-19 22:00:55 -0500172 dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)
173
Brad Bishop84e73b52016-05-12 15:57:52 -0400174 bus = get_dbus()
Norman James3f97c5d2015-08-26 17:44:14 -0500175 obj = ChassisControlObject(bus, OBJ_NAME)
Norman James6f8d0422015-09-14 18:48:00 -0500176 mainloop = gobject.MainLoop()
Brad Bishopf0f3efe2016-06-29 23:20:24 -0400177
178 obj.unmask_signals()
Brad Bishop70852a32016-06-29 22:58:51 -0400179 name = dbus.service.BusName(DBUS_NAME, bus)
Andrew Geisslerb7f40b52016-06-29 15:49:26 -0500180
CamVan Nguyend65b2d52018-02-27 15:14:41 -0600181 print("Running ChassisControlService")
Norman Jamese2765102015-08-19 22:00:55 -0500182 mainloop.run()
Brad Bishop53066752016-09-21 08:48:04 -0400183
184# vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4