@@ -35,6 +35,7 @@
from qemu.qmp import ExecuteError
from .qom_common import QOMCommand
+from .qom_common import ObjectNode
try:
@@ -224,28 +225,27 @@ def __init__(self, args: argparse.Namespace):
super().__init__(args)
self.path = args.path
- def _list_node(self, path: str) -> None:
+ def _list_node(self, node: ObjectNode, path: str) -> None:
print(path)
- items = self.qom_list(path)
- for item in items:
- if item.child:
- continue
- try:
- rsp = self.qmp.cmd('qom-get', path=path,
- property=item.name)
- print(f" {item.name}: {rsp} ({item.type})")
- except ExecuteError as err:
- print(f" {item.name}: <EXCEPTION: {err!s}> ({item.type})")
+
+ for item in node.properties:
+ value = item.value
+ if value == None:
+ value = f"<EXCEPTION: {item.error}>"
+ print(f" {item.name}: {value} ({item.type})")
+
print('')
- for item in items:
- if not item.child:
- continue
- if path == '/':
- path = ''
- self._list_node(f"{path}/{item.name}")
+ if path == '/':
+ path = ''
+
+ for child in node.children:
+ self._list_tree(child, f"{path}/{child.name}")
+
def run(self) -> int:
- self._list_node(self.path)
+ root = self.qom_tree_get(self.path)
+ self._list_node(root, self.path)
+
return 0
@@ -65,6 +65,49 @@ def link(self) -> bool:
return self.type.startswith('link<')
+class ObjectPropertyValue:
+ """
+ Represents a property return from e.g. qom-tree-get
+ """
+ def __init__(self, name: str, type_: str, value: object, error: str):
+ self.name = name
+ self.type = type_
+ self.value = value
+ self.error = error
+
+ @classmethod
+ def make(cls, value: Dict[str, Any]) -> 'ObjectPropertyValue':
+ """
+ Build an ObjectPropertyValue from a Dict with an unknown shape.
+ """
+ assert value.keys() >= {'name', 'type'}
+ assert value.keys() <= {'name', 'type', 'value', 'error'}
+ return cls(value['name'], value['type'],
+ value.get('value'), value.get('error'))
+
+
+class ObjectNode:
+ """
+ Represents the return type from e.g. qom-tree-get
+ """
+ def __init__(self, name: str, children: List['ObjectNode'],
+ properties: List[ObjectPropertyValue]):
+ self.name = name
+ self.children = children
+ self.properties = properties
+
+ @classmethod
+ def make(cls, value: Dict[str, Any]) -> 'ObjectNode':
+ """
+ Build an ObjectNode from a Dict with an unknown shape.
+ """
+ assert value.keys() == {'name', 'children', 'properties'}
+
+ props = [ObjectPropertyValue.make(x) for x in value['properties']]
+ children = [ObjectNode.make(x) for x in value['children']]
+ return cls(value['name'], children, props)
+
+
CommandT = TypeVar('CommandT', bound='QOMCommand')
@@ -145,6 +188,13 @@ def qom_list(self, path: str) -> List[ObjectPropertyInfo]:
assert isinstance(rsp, list)
return [ObjectPropertyInfo.make(x) for x in rsp]
+ def qom_tree_get(self, path: str) -> ObjectNode:
+ """
+ :return: a strongly typed root node from the 'qom-tree-get' command.
+ """
+ rsp = self.qmp.cmd('qom-tree-get', path=path)
+ return ObjectNode.make(rsp)
+
@classmethod
def command_runner(
cls: Type[CommandT],
Use qom-tree-get to speed up the qom-tree command. Signed-off-by: Steve Sistare <steven.sistare@oracle.com> --- python/qemu/utils/qom.py | 36 ++++++++++++++--------------- python/qemu/utils/qom_common.py | 50 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 68 insertions(+), 18 deletions(-)