]> Git Repo - qemu.git/blob - python/qemu/utils/qom.py
works with less than base ISA qemu-system-riscv32 -M virt -bios none -kernel output...
[qemu.git] / python / qemu / utils / qom.py
1 """
2 QEMU Object Model testing tools.
3
4 usage: qom [-h] {set,get,list,tree,fuse} ...
5
6 Query and manipulate QOM data
7
8 optional arguments:
9   -h, --help           show this help message and exit
10
11 QOM commands:
12   {set,get,list,tree,fuse}
13     set                Set a QOM property value
14     get                Get a QOM property value
15     list               List QOM properties at a given path
16     tree               Show QOM tree from a given path
17     fuse               Mount a QOM tree as a FUSE filesystem
18 """
19 ##
20 # Copyright John Snow 2020, for Red Hat, Inc.
21 # Copyright IBM, Corp. 2011
22 #
23 # Authors:
24 #  John Snow <[email protected]>
25 #  Anthony Liguori <[email protected]>
26 #
27 # This work is licensed under the terms of the GNU GPL, version 2 or later.
28 # See the COPYING file in the top-level directory.
29 #
30 # Based on ./scripts/qmp/qom-[set|get|tree|list]
31 ##
32
33 import argparse
34
35 from qemu.qmp import ExecuteError
36
37 from .qom_common import QOMCommand
38
39
40 try:
41     from .qom_fuse import QOMFuse
42 except ModuleNotFoundError as _err:
43     if _err.name != 'fuse':
44         raise
45 else:
46     assert issubclass(QOMFuse, QOMCommand)
47
48
49 class QOMSet(QOMCommand):
50     """
51     QOM Command - Set a property to a given value.
52
53     usage: qom-set [-h] [--socket SOCKET] <path>.<property> <value>
54
55     Set a QOM property value
56
57     positional arguments:
58       <path>.<property>     QOM path and property, separated by a period '.'
59       <value>               new QOM property value
60
61     optional arguments:
62       -h, --help            show this help message and exit
63       --socket SOCKET, -s SOCKET
64                             QMP socket path or address (addr:port). May also be
65                             set via QMP_SOCKET environment variable.
66     """
67     name = 'set'
68     help = 'Set a QOM property value'
69
70     @classmethod
71     def configure_parser(cls, parser: argparse.ArgumentParser) -> None:
72         super().configure_parser(parser)
73         cls.add_path_prop_arg(parser)
74         parser.add_argument(
75             'value',
76             metavar='<value>',
77             action='store',
78             help='new QOM property value'
79         )
80
81     def __init__(self, args: argparse.Namespace):
82         super().__init__(args)
83         self.path, self.prop = args.path_prop.rsplit('.', 1)
84         self.value = args.value
85
86     def run(self) -> int:
87         rsp = self.qmp.command(
88             'qom-set',
89             path=self.path,
90             property=self.prop,
91             value=self.value
92         )
93         print(rsp)
94         return 0
95
96
97 class QOMGet(QOMCommand):
98     """
99     QOM Command - Get a property's current value.
100
101     usage: qom-get [-h] [--socket SOCKET] <path>.<property>
102
103     Get a QOM property value
104
105     positional arguments:
106       <path>.<property>     QOM path and property, separated by a period '.'
107
108     optional arguments:
109       -h, --help            show this help message and exit
110       --socket SOCKET, -s SOCKET
111                             QMP socket path or address (addr:port). May also be
112                             set via QMP_SOCKET environment variable.
113     """
114     name = 'get'
115     help = 'Get a QOM property value'
116
117     @classmethod
118     def configure_parser(cls, parser: argparse.ArgumentParser) -> None:
119         super().configure_parser(parser)
120         cls.add_path_prop_arg(parser)
121
122     def __init__(self, args: argparse.Namespace):
123         super().__init__(args)
124         try:
125             tmp = args.path_prop.rsplit('.', 1)
126         except ValueError as err:
127             raise ValueError('Invalid format for <path>.<property>') from err
128         self.path = tmp[0]
129         self.prop = tmp[1]
130
131     def run(self) -> int:
132         rsp = self.qmp.command(
133             'qom-get',
134             path=self.path,
135             property=self.prop
136         )
137         if isinstance(rsp, dict):
138             for key, value in rsp.items():
139                 print(f"{key}: {value}")
140         else:
141             print(rsp)
142         return 0
143
144
145 class QOMList(QOMCommand):
146     """
147     QOM Command - List the properties at a given path.
148
149     usage: qom-list [-h] [--socket SOCKET] <path>
150
151     List QOM properties at a given path
152
153     positional arguments:
154       <path>                QOM path
155
156     optional arguments:
157       -h, --help            show this help message and exit
158       --socket SOCKET, -s SOCKET
159                             QMP socket path or address (addr:port). May also be
160                             set via QMP_SOCKET environment variable.
161     """
162     name = 'list'
163     help = 'List QOM properties at a given path'
164
165     @classmethod
166     def configure_parser(cls, parser: argparse.ArgumentParser) -> None:
167         super().configure_parser(parser)
168         parser.add_argument(
169             'path',
170             metavar='<path>',
171             action='store',
172             help='QOM path',
173         )
174
175     def __init__(self, args: argparse.Namespace):
176         super().__init__(args)
177         self.path = args.path
178
179     def run(self) -> int:
180         rsp = self.qom_list(self.path)
181         for item in rsp:
182             if item.child:
183                 print(f"{item.name}/")
184             elif item.link:
185                 print(f"@{item.name}/")
186             else:
187                 print(item.name)
188         return 0
189
190
191 class QOMTree(QOMCommand):
192     """
193     QOM Command - Show the full tree below a given path.
194
195     usage: qom-tree [-h] [--socket SOCKET] [<path>]
196
197     Show QOM tree from a given path
198
199     positional arguments:
200       <path>                QOM path
201
202     optional arguments:
203       -h, --help            show this help message and exit
204       --socket SOCKET, -s SOCKET
205                             QMP socket path or address (addr:port). May also be
206                             set via QMP_SOCKET environment variable.
207     """
208     name = 'tree'
209     help = 'Show QOM tree from a given path'
210
211     @classmethod
212     def configure_parser(cls, parser: argparse.ArgumentParser) -> None:
213         super().configure_parser(parser)
214         parser.add_argument(
215             'path',
216             metavar='<path>',
217             action='store',
218             help='QOM path',
219             nargs='?',
220             default='/'
221         )
222
223     def __init__(self, args: argparse.Namespace):
224         super().__init__(args)
225         self.path = args.path
226
227     def _list_node(self, path: str) -> None:
228         print(path)
229         items = self.qom_list(path)
230         for item in items:
231             if item.child:
232                 continue
233             try:
234                 rsp = self.qmp.command('qom-get', path=path,
235                                        property=item.name)
236                 print(f"  {item.name}: {rsp} ({item.type})")
237             except ExecuteError as err:
238                 print(f"  {item.name}: <EXCEPTION: {err!s}> ({item.type})")
239         print('')
240         for item in items:
241             if not item.child:
242                 continue
243             if path == '/':
244                 path = ''
245             self._list_node(f"{path}/{item.name}")
246
247     def run(self) -> int:
248         self._list_node(self.path)
249         return 0
250
251
252 def main() -> int:
253     """QOM script main entry point."""
254     parser = argparse.ArgumentParser(
255         description='Query and manipulate QOM data'
256     )
257     subparsers = parser.add_subparsers(
258         title='QOM commands',
259         dest='command'
260     )
261
262     for command in QOMCommand.__subclasses__():
263         command.register(subparsers)
264
265     args = parser.parse_args()
266
267     if args.command is None:
268         parser.error('Command not specified.')
269         return 1
270
271     cmd_class = args.cmd_class
272     assert isinstance(cmd_class, type(QOMCommand))
273     return cmd_class.command_runner(args)
This page took 0.043119 seconds and 4 git commands to generate.