aboutsummaryrefslogtreecommitdiff
path: root/scripts/qmp/qmp
blob: 514b539a6b202051410119cce3ecdb39307c53d7 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
#!/usr/bin/python
#
# QMP command line tool
#
# Copyright IBM, Corp. 2011
#
# Authors:
#  Anthony Liguori <aliguori@us.ibm.com>
#
# This work is licensed under the terms of the GNU GPLv2 or later.
# See the COPYING file in the top-level directory.

import sys, os
from qmp import QEMUMonitorProtocol

def print_response(rsp, prefix=[]):
    if type(rsp) == list:
        i = 0
        for item in rsp:
            if prefix == []:
                prefix = ['item']
            print_response(item, prefix[:-1] + ['%s[%d]' % (prefix[-1], i)])
            i += 1
    elif type(rsp) == dict:
        for key in rsp.keys():
            print_response(rsp[key], prefix + [key])
    else:
        if len(prefix):
            print '%s: %s' % ('.'.join(prefix), rsp)
        else:
            print '%s' % (rsp)

def main(args):
    path = None

    # Use QMP_PATH if it's set
    if os.environ.has_key('QMP_PATH'):
        path = os.environ['QMP_PATH']

    while len(args):
        arg = args[0]

        if arg.startswith('--'):
            arg = arg[2:]
            if arg.find('=') == -1:
                value = True
            else:
                arg, value = arg.split('=', 1)

            if arg in ['path']:
                if type(value) == str:
                    path = value
            elif arg in ['help']:
                os.execlp('man', 'man', 'qmp')
            else:
                print 'Unknown argument "%s"' % arg

            args = args[1:]
        else:
            break

    if not path:
        print "QMP path isn't set, use --path=qmp-monitor-address or set QMP_PATH"
        return 1

    if len(args):
        command, args = args[0], args[1:]
    else:
        print 'No command found'
        print 'Usage: "qmp [--path=qmp-monitor-address] qmp-cmd arguments"'
        return 1

    if command in ['help']:
        os.execlp('man', 'man', 'qmp')

    srv = QEMUMonitorProtocol(path)
    srv.connect()

    def do_command(srv, cmd, **kwds):
        rsp = srv.cmd(cmd, kwds)
        if rsp.has_key('error'):
            raise Exception(rsp['error']['desc'])
        return rsp['return']

    commands = map(lambda x: x['name'], do_command(srv, 'query-commands'))

    srv.close()

    if command not in commands:
        fullcmd = 'qmp-%s' % command
        try:
            os.environ['QMP_PATH'] = path
            os.execvp(fullcmd, [fullcmd] + args)
        except OSError as exc:
            if exc.errno == 2:
                print 'Command "%s" not found.' % (fullcmd)
                return 1
            raise
        return 0

    srv = QEMUMonitorProtocol(path)
    srv.connect()

    arguments = {}
    for arg in args:
        if not arg.startswith('--'):
            print 'Unknown argument "%s"' % arg
            return 1

        arg = arg[2:]
        if arg.find('=') == -1:
            value = True
        else:
            arg, value = arg.split('=', 1)

        if arg in ['help']:
            os.execlp('man', 'man', 'qmp-%s' % command)
            return 1

        arguments[arg] = value

    rsp = do_command(srv, command, **arguments)
    print_response(rsp)

if __name__ == '__main__':
    sys.exit(main(sys.argv[1:]))