xref: /qemu/scripts/qmp/qmp (revision abff1abf)
1#!/usr/bin/env python3
2#
3# QMP command line tool
4#
5# Copyright IBM, Corp. 2011
6#
7# Authors:
8#  Anthony Liguori <aliguori@us.ibm.com>
9#
10# This work is licensed under the terms of the GNU GPLv2 or later.
11# See the COPYING file in the top-level directory.
12
13import sys, os
14
15sys.path.append(os.path.join(os.path.dirname(__file__), '..', '..', 'python'))
16from qemu.qmp import QEMUMonitorProtocol
17
18def print_response(rsp, prefix=[]):
19    if type(rsp) == list:
20        i = 0
21        for item in rsp:
22            if prefix == []:
23                prefix = ['item']
24            print_response(item, prefix[:-1] + ['%s[%d]' % (prefix[-1], i)])
25            i += 1
26    elif type(rsp) == dict:
27        for key in rsp.keys():
28            print_response(rsp[key], prefix + [key])
29    else:
30        if len(prefix):
31            print('%s: %s' % ('.'.join(prefix), rsp))
32        else:
33            print('%s' % (rsp))
34
35def main(args):
36    path = None
37
38    # Use QMP_PATH if it's set
39    if 'QMP_PATH' in os.environ:
40        path = os.environ['QMP_PATH']
41
42    while len(args):
43        arg = args[0]
44
45        if arg.startswith('--'):
46            arg = arg[2:]
47            if arg.find('=') == -1:
48                value = True
49            else:
50                arg, value = arg.split('=', 1)
51
52            if arg in ['path']:
53                if type(value) == str:
54                    path = value
55            elif arg in ['help']:
56                os.execlp('man', 'man', 'qmp')
57            else:
58                print('Unknown argument "%s"' % arg)
59
60            args = args[1:]
61        else:
62            break
63
64    if not path:
65        print("QMP path isn't set, use --path=qmp-monitor-address or set QMP_PATH")
66        return 1
67
68    if len(args):
69        command, args = args[0], args[1:]
70    else:
71        print('No command found')
72        print('Usage: "qmp [--path=qmp-monitor-address] qmp-cmd arguments"')
73        return 1
74
75    if command in ['help']:
76        os.execlp('man', 'man', 'qmp')
77
78    srv = QEMUMonitorProtocol(path)
79    srv.connect()
80
81    def do_command(srv, cmd, **kwds):
82        rsp = srv.cmd(cmd, kwds)
83        if 'error' in rsp:
84            raise Exception(rsp['error']['desc'])
85        return rsp['return']
86
87    commands = map(lambda x: x['name'], do_command(srv, 'query-commands'))
88
89    srv.close()
90
91    if command not in commands:
92        fullcmd = 'qmp-%s' % command
93        try:
94            os.environ['QMP_PATH'] = path
95            os.execvp(fullcmd, [fullcmd] + args)
96        except OSError as exc:
97            if exc.errno == 2:
98                print('Command "%s" not found.' % (fullcmd))
99                return 1
100            raise
101        return 0
102
103    srv = QEMUMonitorProtocol(path)
104    srv.connect()
105
106    arguments = {}
107    for arg in args:
108        if not arg.startswith('--'):
109            print('Unknown argument "%s"' % arg)
110            return 1
111
112        arg = arg[2:]
113        if arg.find('=') == -1:
114            value = True
115        else:
116            arg, value = arg.split('=', 1)
117
118        if arg in ['help']:
119            os.execlp('man', 'man', 'qmp-%s' % command)
120            return 1
121
122        arguments[arg] = value
123
124    rsp = do_command(srv, command, **arguments)
125    print_response(rsp)
126
127if __name__ == '__main__':
128    sys.exit(main(sys.argv[1:]))
129