Norman James | b4914ad | 2015-10-26 07:14:29 -0500 | [diff] [blame] | 1 | #!/usr/bin/python |
| 2 | |
| 3 | import sys |
Norman James | b4914ad | 2015-10-26 07:14:29 -0500 | [diff] [blame] | 4 | import dbus |
Andrew Jeffery | 0b6883d | 2017-10-11 22:08:55 +1030 | [diff] [blame] | 5 | import argparse |
Norman James | b4914ad | 2015-10-26 07:14:29 -0500 | [diff] [blame] | 6 | |
Andrew Jeffery | de4ed02 | 2017-10-12 01:26:55 +1030 | [diff] [blame^] | 7 | from dbus.mainloop.glib import DBusGMainLoop |
| 8 | import gobject |
| 9 | |
Andrew Jeffery | c6b5deb | 2017-10-11 22:18:27 +1030 | [diff] [blame] | 10 | descriptors = { |
Andrew Geissler | cae038e | 2016-12-19 15:29:10 -0600 | [diff] [blame] | 11 | 'power': { |
| 12 | 'bus_name': 'org.openbmc.control.Power', |
| 13 | 'object_name': '/org/openbmc/control/power0', |
| 14 | 'interface_name': 'org.openbmc.control.Power' |
| 15 | }, |
Andrew Geissler | 2cbbb67 | 2017-05-17 10:52:49 -0500 | [diff] [blame] | 16 | 'chassison': { |
| 17 | 'bus_name': 'xyz.openbmc_project.State.Chassis', |
| 18 | 'object_name': '/xyz/openbmc_project/state/chassis0', |
| 19 | 'interface_name': 'xyz.openbmc_project.State.Chassis', |
| 20 | 'property': 'RequestedPowerTransition', |
Andrew Jeffery | de4ed02 | 2017-10-12 01:26:55 +1030 | [diff] [blame^] | 21 | 'value': 'xyz.openbmc_project.State.Chassis.Transition.On', |
| 22 | 'monitor': 'obmc-chassis-poweron@0.target', |
Andrew Geissler | 2cbbb67 | 2017-05-17 10:52:49 -0500 | [diff] [blame] | 23 | }, |
| 24 | 'chassisoff': { |
| 25 | 'bus_name': 'xyz.openbmc_project.State.Chassis', |
| 26 | 'object_name': '/xyz/openbmc_project/state/chassis0', |
| 27 | 'interface_name': 'xyz.openbmc_project.State.Chassis', |
| 28 | 'property': 'RequestedPowerTransition', |
Andrew Jeffery | de4ed02 | 2017-10-12 01:26:55 +1030 | [diff] [blame^] | 29 | 'value': 'xyz.openbmc_project.State.Chassis.Transition.Off', |
| 30 | 'monitor': 'obmc-chassis-hard-poweroff@0.target', |
Andrew Geissler | 2cbbb67 | 2017-05-17 10:52:49 -0500 | [diff] [blame] | 31 | }, |
Andrew Geissler | cae038e | 2016-12-19 15:29:10 -0600 | [diff] [blame] | 32 | 'poweron': { |
Andrew Geissler | 25b9a85 | 2016-12-19 16:14:09 -0600 | [diff] [blame] | 33 | 'bus_name': 'xyz.openbmc_project.State.Host', |
| 34 | 'object_name': '/xyz/openbmc_project/state/host0', |
| 35 | 'interface_name': 'xyz.openbmc_project.State.Host', |
| 36 | 'property': 'RequestedHostTransition', |
Andrew Jeffery | de4ed02 | 2017-10-12 01:26:55 +1030 | [diff] [blame^] | 37 | 'value': 'xyz.openbmc_project.State.Host.Transition.On', |
| 38 | 'monitor': 'obmc-host-start@0.target', |
Andrew Geissler | cae038e | 2016-12-19 15:29:10 -0600 | [diff] [blame] | 39 | }, |
| 40 | 'poweroff': { |
Andrew Geissler | 25b9a85 | 2016-12-19 16:14:09 -0600 | [diff] [blame] | 41 | 'bus_name': 'xyz.openbmc_project.State.Host', |
| 42 | 'object_name': '/xyz/openbmc_project/state/host0', |
| 43 | 'interface_name': 'xyz.openbmc_project.State.Host', |
| 44 | 'property': 'RequestedHostTransition', |
Andrew Jeffery | de4ed02 | 2017-10-12 01:26:55 +1030 | [diff] [blame^] | 45 | 'value': 'xyz.openbmc_project.State.Host.Transition.Off', |
| 46 | 'monitor': 'obmc-host-stop@0.target', |
Andrew Geissler | cae038e | 2016-12-19 15:29:10 -0600 | [diff] [blame] | 47 | }, |
Andrew Geissler | 8f8cbce | 2017-02-20 16:10:26 -0600 | [diff] [blame] | 48 | 'bmcstate': { |
| 49 | 'bus_name': 'xyz.openbmc_project.State.BMC', |
| 50 | 'object_name': '/xyz/openbmc_project/state/bmc0', |
| 51 | 'interface_name': 'xyz.openbmc_project.State.BMC', |
| 52 | 'property': 'CurrentBMCState', |
| 53 | }, |
| 54 | 'chassisstate': { |
| 55 | 'bus_name': 'xyz.openbmc_project.State.Chassis', |
| 56 | 'object_name': '/xyz/openbmc_project/state/chassis0', |
| 57 | 'interface_name': 'xyz.openbmc_project.State.Chassis', |
| 58 | 'property': 'CurrentPowerState', |
| 59 | }, |
| 60 | 'hoststate': { |
| 61 | 'bus_name': 'xyz.openbmc_project.State.Host', |
| 62 | 'object_name': '/xyz/openbmc_project/state/host0', |
| 63 | 'interface_name': 'xyz.openbmc_project.State.Host', |
| 64 | 'property': 'CurrentHostState', |
Andrew Geissler | cae038e | 2016-12-19 15:29:10 -0600 | [diff] [blame] | 65 | }, |
| 66 | 'bootprogress': { |
George Keishing | 3be0995 | 2017-08-18 09:48:03 -0500 | [diff] [blame] | 67 | 'bus_name': 'xyz.openbmc_project.State.Host', |
| 68 | 'object_name': '/xyz/openbmc_project/state/host0', |
| 69 | 'interface_name': 'xyz.openbmc_project.State.Boot.Progress', |
| 70 | 'property': 'BootProgress', |
Andrew Geissler | cae038e | 2016-12-19 15:29:10 -0600 | [diff] [blame] | 71 | }, |
Andrew Jeffery | 0b6883d | 2017-10-11 22:08:55 +1030 | [diff] [blame] | 72 | 'state' : ['bmcstate', 'chassisstate', 'hoststate'] |
Norman James | b4914ad | 2015-10-26 07:14:29 -0500 | [diff] [blame] | 73 | } |
| 74 | |
Andrew Jeffery | de4ed02 | 2017-10-12 01:26:55 +1030 | [diff] [blame^] | 75 | def run_set_property(dbus_bus, dbus_iface, descriptor, args): |
| 76 | mainloop = gobject.MainLoop() |
| 77 | |
| 78 | iface = descriptor['interface_name'] |
| 79 | prop = descriptor['property'] |
| 80 | |
| 81 | if 'monitor' not in descriptor: |
| 82 | dbus_iface.Set(iface, prop, descriptor['value']) |
| 83 | return True |
| 84 | |
| 85 | def property_listener(job, path, unit, state): |
| 86 | if descriptor['monitor'] != unit: |
| 87 | return |
| 88 | |
| 89 | property_listener.success = (state == 'done') |
| 90 | mainloop.quit() |
| 91 | |
| 92 | property_listener.success = True |
| 93 | |
| 94 | if args.wait: |
| 95 | sig_match = dbus_bus.add_signal_receiver(property_listener, "JobRemoved") |
| 96 | |
| 97 | dbus_iface.Set(iface, prop, descriptor['value']) |
| 98 | |
| 99 | if args.wait: |
| 100 | mainloop.run() |
| 101 | sig_match.remove() |
| 102 | |
| 103 | return property_listener.success |
| 104 | |
| 105 | def run_one_command(dbus_bus, descriptor, args): |
Andrew Jeffery | c6b5deb | 2017-10-11 22:18:27 +1030 | [diff] [blame] | 106 | bus = descriptor['bus_name'] |
| 107 | obj = descriptor['object_name'] |
| 108 | iface = descriptor['interface_name'] |
Andrew Jeffery | e4dcaef | 2017-10-11 18:08:01 +1030 | [diff] [blame] | 109 | dbus_obj = dbus_bus.get_object(bus, obj) |
Andrew Jeffery | de4ed02 | 2017-10-12 01:26:55 +1030 | [diff] [blame^] | 110 | result = None |
Andrew Jeffery | e4dcaef | 2017-10-11 18:08:01 +1030 | [diff] [blame] | 111 | |
Andrew Jeffery | c6b5deb | 2017-10-11 22:18:27 +1030 | [diff] [blame] | 112 | if (descriptor.has_key('property')): |
Andrew Jeffery | e4dcaef | 2017-10-11 18:08:01 +1030 | [diff] [blame] | 113 | dbus_iface = dbus.Interface(dbus_obj, "org.freedesktop.DBus.Properties") |
Andrew Jeffery | c6b5deb | 2017-10-11 22:18:27 +1030 | [diff] [blame] | 114 | if descriptor.has_key('value'): |
Andrew Jeffery | de4ed02 | 2017-10-12 01:26:55 +1030 | [diff] [blame^] | 115 | result = run_set_property(dbus_bus, dbus_iface, descriptor, args) |
Andrew Jeffery | e4dcaef | 2017-10-11 18:08:01 +1030 | [diff] [blame] | 116 | else: |
Andrew Jeffery | de4ed02 | 2017-10-12 01:26:55 +1030 | [diff] [blame^] | 117 | prop = descriptor['property'] |
Andrew Jeffery | e4dcaef | 2017-10-11 18:08:01 +1030 | [diff] [blame] | 118 | dbus_prop = dbus_iface.Get(iface, prop) |
| 119 | print '{:<20}: {}'.format(prop, str(dbus_prop)) |
Andrew Jeffery | de4ed02 | 2017-10-12 01:26:55 +1030 | [diff] [blame^] | 120 | result = True |
Andrew Jeffery | e4dcaef | 2017-10-11 18:08:01 +1030 | [diff] [blame] | 121 | else: |
| 122 | dbus_iface = dbus.Interface(dbus_obj, "org.freedesktop.DBus.Properties") |
| 123 | props = dbus_iface.GetAll(iface) |
| 124 | for p in props: |
Andrew Jeffery | bba82bd | 2017-10-11 22:20:30 +1030 | [diff] [blame] | 125 | print "{} = {}".format(p, str(props[p])) |
Andrew Jeffery | de4ed02 | 2017-10-12 01:26:55 +1030 | [diff] [blame^] | 126 | result = True |
Andrew Jeffery | e4dcaef | 2017-10-11 18:08:01 +1030 | [diff] [blame] | 127 | |
Andrew Jeffery | de4ed02 | 2017-10-12 01:26:55 +1030 | [diff] [blame^] | 128 | return result |
| 129 | |
| 130 | def run_all_commands(dbus_bus, recipe, args): |
Andrew Jeffery | c6b5deb | 2017-10-11 22:18:27 +1030 | [diff] [blame] | 131 | if isinstance(recipe, dict): |
Andrew Jeffery | de4ed02 | 2017-10-12 01:26:55 +1030 | [diff] [blame^] | 132 | return run_one_command(dbus_bus, recipe, args) |
Andrew Jeffery | 7b376e7 | 2017-10-11 18:12:05 +1030 | [diff] [blame] | 133 | |
Andrew Jeffery | c6b5deb | 2017-10-11 22:18:27 +1030 | [diff] [blame] | 134 | assert isinstance(recipe, list) |
| 135 | for command in recipe: |
Andrew Jeffery | de4ed02 | 2017-10-12 01:26:55 +1030 | [diff] [blame^] | 136 | descriptor = descriptors[command] |
| 137 | if not run_one_command(dbus_bus, descriptor, args): |
| 138 | print "Failed to execute command: {}".format(descriptor) |
| 139 | return False |
| 140 | |
| 141 | return True |
Andrew Jeffery | 7b376e7 | 2017-10-11 18:12:05 +1030 | [diff] [blame] | 142 | |
Andrew Jeffery | 44e6d9c | 2017-10-11 16:57:31 +1030 | [diff] [blame] | 143 | def main(): |
Andrew Jeffery | de4ed02 | 2017-10-12 01:26:55 +1030 | [diff] [blame^] | 144 | dbus.mainloop.glib.DBusGMainLoop(set_as_default=True) |
| 145 | |
Andrew Jeffery | 0b6883d | 2017-10-11 22:08:55 +1030 | [diff] [blame] | 146 | parser = argparse.ArgumentParser() |
Andrew Jeffery | de4ed02 | 2017-10-12 01:26:55 +1030 | [diff] [blame^] | 147 | parser.add_argument('--wait', '-w', action='store_true', |
| 148 | help='Block until the state transition succeeds or fails') |
Andrew Jeffery | c6b5deb | 2017-10-11 22:18:27 +1030 | [diff] [blame] | 149 | parser.add_argument('recipe', choices=sorted(descriptors.keys())) |
Andrew Jeffery | 0b6883d | 2017-10-11 22:08:55 +1030 | [diff] [blame] | 150 | args = parser.parse_args() |
Andrew Geissler | 8f8cbce | 2017-02-20 16:10:26 -0600 | [diff] [blame] | 151 | |
Andrew Jeffery | bdb7435 | 2017-10-11 17:29:48 +1030 | [diff] [blame] | 152 | dbus_bus = dbus.SystemBus() |
Andrew Jeffery | 0b6883d | 2017-10-11 22:08:55 +1030 | [diff] [blame] | 153 | try: |
Andrew Jeffery | de4ed02 | 2017-10-12 01:26:55 +1030 | [diff] [blame^] | 154 | return run_all_commands(dbus_bus, descriptors[args.recipe], args) |
Andrew Jeffery | 0b6883d | 2017-10-11 22:08:55 +1030 | [diff] [blame] | 155 | finally: |
| 156 | dbus_bus.close() |
Andrew Jeffery | 44e6d9c | 2017-10-11 16:57:31 +1030 | [diff] [blame] | 157 | |
| 158 | if __name__ == "__main__": |
Andrew Jeffery | de4ed02 | 2017-10-12 01:26:55 +1030 | [diff] [blame^] | 159 | sys.exit(0 if main() else 1) |