blob: 7f9631685f1e77453d1e00482527d3a0349a6023 [file] [log] [blame]
Brad Bishopceb44362016-07-25 09:14:00 -04001# Contributors Listed Below - COPYRIGHT 2016
2# [+] International Business Machines Corp.
3#
4#
5# Licensed under the Apache License, Version 2.0 (the "License");
6# you may not use this file except in compliance with the License.
7# You may obtain a copy of the License at
8#
9# http://www.apache.org/licenses/LICENSE-2.0
10#
11# Unless required by applicable law or agreed to in writing, software
12# distributed under the License is distributed on an "AS IS" BASIS,
13# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
14# implied. See the License for the specific language governing
15# permissions and limitations under the License.
16
17import sys
18import dbus
19import dbus.mainloop.glib
20import gobject
21import obmc.dbuslib.enums
22import obmc.mapper
23import obmc.mapper.utils
24import optparse
25
26
27def add_systemd_path_option(parser):
28 parser.add_option(
29 '-s', '--systemd', action='store_true', default=False,
30 help='interpret-dash-delimited-path-arguments-as-paths')
31
32
33def systemd_to_dbus(item):
34 if not item.startswith('/'):
35 item = '/%s' % item.replace('-', '/')
36 return item
37
38
39class CallApp(object):
40 usage = 'OBJECTPATH INTERFACE METHOD ARGUMENTS...'
41 description = 'Invoke a DBus method on the named DBus object.'
42
43 def setup(self, parser, command):
44 add_systemd_path_option(parser)
45
46 def main(self, parser):
47 args = parser.largs
48 try:
49 path, interface, method, parameters = \
50 args[0], args[1], args[2], args[3:]
51 except IndexError:
52 parser.error('Not enough arguments')
53
54 bus = dbus.SystemBus()
55 mapper = obmc.mapper.Mapper(bus)
56 if parser.values.systemd:
57 path = systemd_to_dbus(path)
58
59 try:
60 service_info = mapper.get_object(path)
61 except dbus.exceptions.DBusException, e:
62 if e.get_dbus_name() != obmc.mapper.MAPPER_NOT_FOUND:
63 raise
64 parser.error('\'%s\' was not found' % path)
65
66 obj = bus.get_object(list(service_info)[0], path, introspect=False)
67 iface = dbus.Interface(obj, interface)
68 func = getattr(iface, method)
69 try:
70 return func(*parameters)
71 except dbus.exceptions.DBusException, e:
72 if e.get_dbus_name() != obmc.dbuslib.enums.DBUS_UNKNOWN_METHOD:
73 raise
74 parser.error(
75 '\'%s.%s\' is not a valid method for \'%s\''
76 % (interface, method, path))
77
78
79class WaitApp(object):
80 usage = 'OBJECTPATH...'
81 description = 'Wait for one or more DBus ' \
82 'object(s) to appear on the system bus.'
83
84 def setup(self, parser, command):
85 add_systemd_path_option(parser)
86
87 def main(self, parser):
88 if not parser.largs:
89 parser.error('Specify one or more object paths')
90
91 dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)
92 loop = gobject.MainLoop()
93 bus = dbus.SystemBus()
94 if parser.values.systemd:
95 waitlist = [systemd_to_dbus(x) for x in parser.largs]
96 else:
97 waitlist = parser.largs
98
99 waiter = obmc.mapper.utils.Wait(bus, waitlist, callback=loop.quit)
100 loop.run()
101
102
103def mapper_main():
104 all_commands = []
105 usage = '''%prog [options] SUBCOMMAND\n\nSUBCOMMANDS:\n'''
106 for k, v in sys.modules[__name__].__dict__.iteritems():
107 if k.endswith('App'):
108 all_commands.append(k.replace('App', '').lower())
109 usage += ' %s - %s\n' % (all_commands[-1], v.description)
110
111 parser = optparse.OptionParser(usage=usage)
112 commands = list(set(sys.argv[1:]).intersection(all_commands))
113 if len(commands) != 1:
114 parser.error('Specify a single sub-command')
115
116 classname = '%sApp' % commands[0].capitalize()
117 cls = getattr(sys.modules[__name__], classname)
118 usage = getattr(cls, 'usage')
119
120 parser.set_usage('%%prog %s [options] %s' % (commands[0], usage))
121 inst = cls()
122 inst.setup(parser, commands[0])
123 opts, args = parser.parse_args()
124 parser.largs = parser.largs[1:]
125 return inst.main(parser)