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