maqet 0.0.1.3__py3-none-any.whl → 0.0.5__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (83) hide show
  1. maqet/__init__.py +50 -6
  2. maqet/__main__.py +96 -0
  3. maqet/__version__.py +3 -0
  4. maqet/api/__init__.py +35 -0
  5. maqet/api/decorators.py +184 -0
  6. maqet/api/metadata.py +147 -0
  7. maqet/api/registry.py +182 -0
  8. maqet/cli.py +71 -0
  9. maqet/config/__init__.py +26 -0
  10. maqet/config/merger.py +237 -0
  11. maqet/config/parser.py +198 -0
  12. maqet/config/validators.py +519 -0
  13. maqet/config_handlers.py +684 -0
  14. maqet/constants.py +200 -0
  15. maqet/exceptions.py +226 -0
  16. maqet/formatters.py +294 -0
  17. maqet/generators/__init__.py +12 -0
  18. maqet/generators/base_generator.py +101 -0
  19. maqet/generators/cli_generator.py +635 -0
  20. maqet/generators/python_generator.py +247 -0
  21. maqet/generators/rest_generator.py +58 -0
  22. maqet/handlers/__init__.py +12 -0
  23. maqet/handlers/base.py +108 -0
  24. maqet/handlers/init.py +147 -0
  25. maqet/handlers/stage.py +196 -0
  26. maqet/ipc/__init__.py +29 -0
  27. maqet/ipc/retry.py +265 -0
  28. maqet/ipc/runner_client.py +285 -0
  29. maqet/ipc/unix_socket_server.py +239 -0
  30. maqet/logger.py +160 -55
  31. maqet/machine.py +884 -0
  32. maqet/managers/__init__.py +7 -0
  33. maqet/managers/qmp_manager.py +333 -0
  34. maqet/managers/snapshot_coordinator.py +327 -0
  35. maqet/managers/vm_manager.py +683 -0
  36. maqet/maqet.py +1120 -0
  37. maqet/os_interactions.py +46 -0
  38. maqet/process_spawner.py +395 -0
  39. maqet/qemu_args.py +76 -0
  40. maqet/qmp/__init__.py +10 -0
  41. maqet/qmp/commands.py +92 -0
  42. maqet/qmp/keyboard.py +311 -0
  43. maqet/qmp/qmp.py +17 -0
  44. maqet/snapshot.py +473 -0
  45. maqet/state.py +958 -0
  46. maqet/storage.py +702 -162
  47. maqet/validation/__init__.py +9 -0
  48. maqet/validation/config_validator.py +170 -0
  49. maqet/vm_runner.py +523 -0
  50. maqet-0.0.5.dist-info/METADATA +237 -0
  51. maqet-0.0.5.dist-info/RECORD +55 -0
  52. {maqet-0.0.1.3.dist-info → maqet-0.0.5.dist-info}/WHEEL +1 -1
  53. maqet-0.0.5.dist-info/entry_points.txt +2 -0
  54. maqet-0.0.5.dist-info/licenses/LICENSE +21 -0
  55. {maqet-0.0.1.3.dist-info → maqet-0.0.5.dist-info}/top_level.txt +0 -1
  56. maqet/core.py +0 -395
  57. maqet/functions.py +0 -104
  58. maqet-0.0.1.3.dist-info/METADATA +0 -104
  59. maqet-0.0.1.3.dist-info/RECORD +0 -33
  60. qemu/machine/__init__.py +0 -36
  61. qemu/machine/console_socket.py +0 -142
  62. qemu/machine/machine.py +0 -954
  63. qemu/machine/py.typed +0 -0
  64. qemu/machine/qtest.py +0 -191
  65. qemu/qmp/__init__.py +0 -59
  66. qemu/qmp/error.py +0 -50
  67. qemu/qmp/events.py +0 -717
  68. qemu/qmp/legacy.py +0 -319
  69. qemu/qmp/message.py +0 -209
  70. qemu/qmp/models.py +0 -146
  71. qemu/qmp/protocol.py +0 -1057
  72. qemu/qmp/py.typed +0 -0
  73. qemu/qmp/qmp_client.py +0 -655
  74. qemu/qmp/qmp_shell.py +0 -618
  75. qemu/qmp/qmp_tui.py +0 -655
  76. qemu/qmp/util.py +0 -219
  77. qemu/utils/__init__.py +0 -162
  78. qemu/utils/accel.py +0 -84
  79. qemu/utils/py.typed +0 -0
  80. qemu/utils/qemu_ga_client.py +0 -323
  81. qemu/utils/qom.py +0 -273
  82. qemu/utils/qom_common.py +0 -175
  83. qemu/utils/qom_fuse.py +0 -207
qemu/utils/qom_common.py DELETED
@@ -1,175 +0,0 @@
1
- """
2
- QOM Command abstractions.
3
- """
4
- ##
5
- # Copyright John Snow 2020, for Red Hat, Inc.
6
- # Copyright IBM, Corp. 2011
7
- #
8
- # Authors:
9
- # John Snow <jsnow@redhat.com>
10
- # Anthony Liguori <aliguori@amazon.com>
11
- #
12
- # This work is licensed under the terms of the GNU GPL, version 2 or later.
13
- # See the COPYING file in the top-level directory.
14
- #
15
- # Based on ./scripts/qmp/qom-[set|get|tree|list]
16
- ##
17
-
18
- import argparse
19
- import os
20
- import sys
21
- from typing import (
22
- Any,
23
- Dict,
24
- List,
25
- Optional,
26
- Type,
27
- TypeVar,
28
- )
29
-
30
- from qemu.qmp import QMPError
31
- from qemu.qmp.legacy import QEMUMonitorProtocol
32
-
33
-
34
- class ObjectPropertyInfo:
35
- """
36
- Represents the return type from e.g. qom-list.
37
- """
38
- def __init__(self, name: str, type_: str,
39
- description: Optional[str] = None,
40
- default_value: Optional[object] = None):
41
- self.name = name
42
- self.type = type_
43
- self.description = description
44
- self.default_value = default_value
45
-
46
- @classmethod
47
- def make(cls, value: Dict[str, Any]) -> 'ObjectPropertyInfo':
48
- """
49
- Build an ObjectPropertyInfo from a Dict with an unknown shape.
50
- """
51
- assert value.keys() >= {'name', 'type'}
52
- assert value.keys() <= {'name', 'type', 'description', 'default-value'}
53
- return cls(value['name'], value['type'],
54
- value.get('description'),
55
- value.get('default-value'))
56
-
57
- @property
58
- def child(self) -> bool:
59
- """Is this property a child property?"""
60
- return self.type.startswith('child<')
61
-
62
- @property
63
- def link(self) -> bool:
64
- """Is this property a link property?"""
65
- return self.type.startswith('link<')
66
-
67
-
68
- CommandT = TypeVar('CommandT', bound='QOMCommand')
69
-
70
-
71
- class QOMCommand:
72
- """
73
- Represents a QOM sub-command.
74
-
75
- :param args: Parsed arguments, as returned from parser.parse_args.
76
- """
77
- name: str
78
- help: str
79
-
80
- def __init__(self, args: argparse.Namespace):
81
- if args.socket is None:
82
- raise QMPError("No QMP socket path or address given")
83
- self.qmp = QEMUMonitorProtocol(
84
- QEMUMonitorProtocol.parse_address(args.socket)
85
- )
86
- self.qmp.connect()
87
-
88
- @classmethod
89
- def register(cls, subparsers: Any) -> None:
90
- """
91
- Register this command with the argument parser.
92
-
93
- :param subparsers: argparse subparsers object, from "add_subparsers".
94
- """
95
- subparser = subparsers.add_parser(cls.name, help=cls.help,
96
- description=cls.help)
97
- cls.configure_parser(subparser)
98
-
99
- @classmethod
100
- def configure_parser(cls, parser: argparse.ArgumentParser) -> None:
101
- """
102
- Configure a parser with this command's arguments.
103
-
104
- :param parser: argparse parser or subparser object.
105
- """
106
- default_path = os.environ.get('QMP_SOCKET')
107
- parser.add_argument(
108
- '--socket', '-s',
109
- dest='socket',
110
- action='store',
111
- help='QMP socket path or address (addr:port).'
112
- ' May also be set via QMP_SOCKET environment variable.',
113
- default=default_path
114
- )
115
- parser.set_defaults(cmd_class=cls)
116
-
117
- @classmethod
118
- def add_path_prop_arg(cls, parser: argparse.ArgumentParser) -> None:
119
- """
120
- Add the <path>.<proptery> positional argument to this command.
121
-
122
- :param parser: The parser to add the argument to.
123
- """
124
- parser.add_argument(
125
- 'path_prop',
126
- metavar='<path>.<property>',
127
- action='store',
128
- help="QOM path and property, separated by a period '.'"
129
- )
130
-
131
- def run(self) -> int:
132
- """
133
- Run this command.
134
-
135
- :return: 0 on success, 1 otherwise.
136
- """
137
- raise NotImplementedError
138
-
139
- def qom_list(self, path: str) -> List[ObjectPropertyInfo]:
140
- """
141
- :return: a strongly typed list from the 'qom-list' command.
142
- """
143
- rsp = self.qmp.cmd('qom-list', path=path)
144
- # qom-list returns List[ObjectPropertyInfo]
145
- assert isinstance(rsp, list)
146
- return [ObjectPropertyInfo.make(x) for x in rsp]
147
-
148
- @classmethod
149
- def command_runner(
150
- cls: Type[CommandT],
151
- args: argparse.Namespace
152
- ) -> int:
153
- """
154
- Run a fully-parsed subcommand, with error-handling for the CLI.
155
-
156
- :return: The return code from `run()`.
157
- """
158
- try:
159
- cmd = cls(args)
160
- return cmd.run()
161
- except QMPError as err:
162
- print(f"{type(err).__name__}: {err!s}", file=sys.stderr)
163
- return -1
164
-
165
- @classmethod
166
- def entry_point(cls) -> int:
167
- """
168
- Build this command's parser, parse arguments, and run the command.
169
-
170
- :return: `run`'s return code.
171
- """
172
- parser = argparse.ArgumentParser(description=cls.help)
173
- cls.configure_parser(parser)
174
- args = parser.parse_args()
175
- return cls.command_runner(args)
qemu/utils/qom_fuse.py DELETED
@@ -1,207 +0,0 @@
1
- """
2
- QEMU Object Model FUSE filesystem tool
3
-
4
- This script offers a simple FUSE filesystem within which the QOM tree
5
- may be browsed, queried and edited using traditional shell tooling.
6
-
7
- This script requires the 'fusepy' python package.
8
-
9
-
10
- usage: qom-fuse [-h] [--socket SOCKET] <mount>
11
-
12
- Mount a QOM tree as a FUSE filesystem
13
-
14
- positional arguments:
15
- <mount> Mount point
16
-
17
- optional arguments:
18
- -h, --help show this help message and exit
19
- --socket SOCKET, -s SOCKET
20
- QMP socket path or address (addr:port). May also be
21
- set via QMP_SOCKET environment variable.
22
- """
23
- ##
24
- # Copyright IBM, Corp. 2012
25
- # Copyright (C) 2020 Red Hat, Inc.
26
- #
27
- # Authors:
28
- # Anthony Liguori <aliguori@us.ibm.com>
29
- # Markus Armbruster <armbru@redhat.com>
30
- #
31
- # This work is licensed under the terms of the GNU GPL, version 2 or later.
32
- # See the COPYING file in the top-level directory.
33
- ##
34
-
35
- import argparse
36
- from errno import ENOENT, EPERM
37
- import stat
38
- import sys
39
- from typing import (
40
- IO,
41
- Dict,
42
- Iterator,
43
- Mapping,
44
- Optional,
45
- Union,
46
- )
47
-
48
- import fuse
49
- from fuse import FUSE, FuseOSError, Operations
50
-
51
- from qemu.qmp import ExecuteError
52
-
53
- from .qom_common import QOMCommand
54
-
55
-
56
- fuse.fuse_python_api = (0, 2)
57
-
58
-
59
- class QOMFuse(QOMCommand, Operations):
60
- """
61
- QOMFuse implements both fuse.Operations and QOMCommand.
62
-
63
- Operations implements the FS, and QOMCommand implements the CLI command.
64
- """
65
- name = 'fuse'
66
- help = 'Mount a QOM tree as a FUSE filesystem'
67
- fuse: FUSE
68
-
69
- @classmethod
70
- def configure_parser(cls, parser: argparse.ArgumentParser) -> None:
71
- super().configure_parser(parser)
72
- parser.add_argument(
73
- 'mount',
74
- metavar='<mount>',
75
- action='store',
76
- help="Mount point",
77
- )
78
-
79
- def __init__(self, args: argparse.Namespace):
80
- super().__init__(args)
81
- self.mount = args.mount
82
- self.ino_map: Dict[str, int] = {}
83
- self.ino_count = 1
84
-
85
- def run(self) -> int:
86
- print(f"Mounting QOMFS to '{self.mount}'", file=sys.stderr)
87
- self.fuse = FUSE(self, self.mount, foreground=True)
88
- return 0
89
-
90
- def get_ino(self, path: str) -> int:
91
- """Get an inode number for a given QOM path."""
92
- if path in self.ino_map:
93
- return self.ino_map[path]
94
- self.ino_map[path] = self.ino_count
95
- self.ino_count += 1
96
- return self.ino_map[path]
97
-
98
- def is_object(self, path: str) -> bool:
99
- """Is the given QOM path an object?"""
100
- try:
101
- self.qom_list(path)
102
- return True
103
- except ExecuteError:
104
- return False
105
-
106
- def is_property(self, path: str) -> bool:
107
- """Is the given QOM path a property?"""
108
- path, prop = path.rsplit('/', 1)
109
- if path == '':
110
- path = '/'
111
- try:
112
- for item in self.qom_list(path):
113
- if item.name == prop:
114
- return True
115
- return False
116
- except ExecuteError:
117
- return False
118
-
119
- def is_link(self, path: str) -> bool:
120
- """Is the given QOM path a link?"""
121
- path, prop = path.rsplit('/', 1)
122
- if path == '':
123
- path = '/'
124
- try:
125
- for item in self.qom_list(path):
126
- if item.name == prop and item.link:
127
- return True
128
- return False
129
- except ExecuteError:
130
- return False
131
-
132
- def read(self, path: str, size: int, offset: int, fh: IO[bytes]) -> bytes:
133
- if not self.is_property(path):
134
- raise FuseOSError(ENOENT)
135
-
136
- path, prop = path.rsplit('/', 1)
137
- if path == '':
138
- path = '/'
139
- try:
140
- data = str(self.qmp.cmd('qom-get', path=path, property=prop))
141
- data += '\n' # make values shell friendly
142
- except ExecuteError as err:
143
- raise FuseOSError(EPERM) from err
144
-
145
- if offset > len(data):
146
- return b''
147
-
148
- return bytes(data[offset:][:size], encoding='utf-8')
149
-
150
- def readlink(self, path: str) -> Union[bool, str]:
151
- if not self.is_link(path):
152
- return False
153
- path, prop = path.rsplit('/', 1)
154
- prefix = '/'.join(['..'] * (len(path.split('/')) - 1))
155
- return prefix + str(self.qmp.cmd('qom-get', path=path,
156
- property=prop))
157
-
158
- def getattr(self, path: str,
159
- fh: Optional[IO[bytes]] = None) -> Mapping[str, object]:
160
- if self.is_link(path):
161
- value = {
162
- 'st_mode': 0o755 | stat.S_IFLNK,
163
- 'st_ino': self.get_ino(path),
164
- 'st_dev': 0,
165
- 'st_nlink': 2,
166
- 'st_uid': 1000,
167
- 'st_gid': 1000,
168
- 'st_size': 4096,
169
- 'st_atime': 0,
170
- 'st_mtime': 0,
171
- 'st_ctime': 0
172
- }
173
- elif self.is_object(path):
174
- value = {
175
- 'st_mode': 0o755 | stat.S_IFDIR,
176
- 'st_ino': self.get_ino(path),
177
- 'st_dev': 0,
178
- 'st_nlink': 2,
179
- 'st_uid': 1000,
180
- 'st_gid': 1000,
181
- 'st_size': 4096,
182
- 'st_atime': 0,
183
- 'st_mtime': 0,
184
- 'st_ctime': 0
185
- }
186
- elif self.is_property(path):
187
- value = {
188
- 'st_mode': 0o644 | stat.S_IFREG,
189
- 'st_ino': self.get_ino(path),
190
- 'st_dev': 0,
191
- 'st_nlink': 1,
192
- 'st_uid': 1000,
193
- 'st_gid': 1000,
194
- 'st_size': 4096,
195
- 'st_atime': 0,
196
- 'st_mtime': 0,
197
- 'st_ctime': 0
198
- }
199
- else:
200
- raise FuseOSError(ENOENT)
201
- return value
202
-
203
- def readdir(self, path: str, fh: IO[bytes]) -> Iterator[str]:
204
- yield '.'
205
- yield '..'
206
- for item in self.qom_list(path):
207
- yield item.name