From: "Lukáš Doktor" <ldoktor@redhat.com>
To: ldoktor@redhat.com, apahim@redhat.com, qemu-devel@nongnu.org,
famz@redhat.com, armbru@redhat.com, mreitz@redhat.com,
ehabkost@redhat.com
Subject: [Qemu-devel] [PATCH 01/11] qemu.py: Pylint/style fixes
Date: Thu, 20 Jul 2017 18:28:05 +0200 [thread overview]
Message-ID: <20170720162815.19802-2-ldoktor@redhat.com> (raw)
In-Reply-To: <20170720162815.19802-1-ldoktor@redhat.com>
No actual code changes, just several pylint/style fixes and docstring
clarifications.
Signed-off-by: Lukáš Doktor <ldoktor@redhat.com>
---
scripts/qemu.py | 76 ++++++++++++++++++++++++++++++++++++++++-----------------
1 file changed, 53 insertions(+), 23 deletions(-)
diff --git a/scripts/qemu.py b/scripts/qemu.py
index 880e3e8..191c916 100644
--- a/scripts/qemu.py
+++ b/scripts/qemu.py
@@ -23,8 +23,22 @@ import qmp.qmp
class QEMUMachine(object):
'''A QEMU VM'''
- def __init__(self, binary, args=[], wrapper=[], name=None, test_dir="/var/tmp",
- monitor_address=None, socket_scm_helper=None, debug=False):
+ def __init__(self, binary, args=[], wrapper=[], name=None,
+ test_dir="/var/tmp", monitor_address=None,
+ socket_scm_helper=None, debug=False):
+ '''
+ Create a QEMUMachine object
+
+ @param binary: path to the qemu binary (str)
+ @param args: initial list of extra arguments
+ @param wrapper: list of arguments used as prefix to qemu binary
+ @param name: name of this object (used for log/monitor/... file names)
+ @param test_dir: base location to put log/monitor/... files in
+ @param monitor_address: custom address for QMP monitor
+ @param socket_scm_helper: path to scm_helper binary (to forward fds)
+ @param debug: enable debug mode (forwarded to QMP helper and such)
+ @note: Qemu process is not started until launch() is used.
+ '''
if name is None:
name = "qemu-%d" % os.getpid()
if monitor_address is None:
@@ -33,12 +47,13 @@ class QEMUMachine(object):
self._qemu_log_path = os.path.join(test_dir, name + ".log")
self._popen = None
self._binary = binary
- self._args = list(args) # Force copy args in case we modify them
+ self._args = list(args) # Force copy args in case we modify them
self._wrapper = wrapper
self._events = []
self._iolog = None
self._socket_scm_helper = socket_scm_helper
self._debug = debug
+ self._qmp = None
# This can be used to add an unused monitor instance.
def add_monitor_telnet(self, ip, port):
@@ -64,16 +79,16 @@ class QEMUMachine(object):
if self._socket_scm_helper is None:
print >>sys.stderr, "No path to socket_scm_helper set"
return -1
- if os.path.exists(self._socket_scm_helper) == False:
+ if os.path.exists(self._socket_scm_helper) is False:
print >>sys.stderr, "%s does not exist" % self._socket_scm_helper
return -1
fd_param = ["%s" % self._socket_scm_helper,
"%d" % self._qmp.get_sock_fd(),
"%s" % fd_file_path]
devnull = open('/dev/null', 'rb')
- p = subprocess.Popen(fd_param, stdin=devnull, stdout=sys.stdout,
- stderr=sys.stderr)
- return p.wait()
+ proc = subprocess.Popen(fd_param, stdin=devnull, stdout=sys.stdout,
+ stderr=sys.stderr)
+ return proc.wait()
@staticmethod
def _remove_if_exists(path):
@@ -99,8 +114,8 @@ class QEMUMachine(object):
return self._popen.pid
def _load_io_log(self):
- with open(self._qemu_log_path, "r") as fh:
- self._iolog = fh.read()
+ with open(self._qemu_log_path, "r") as iolog:
+ self._iolog = iolog.read()
def _base_args(self):
if isinstance(self._monitor_address, tuple):
@@ -114,8 +129,8 @@ class QEMUMachine(object):
'-display', 'none', '-vga', 'none']
def _pre_launch(self):
- self._qmp = qmp.qmp.QEMUMonitorProtocol(self._monitor_address, server=True,
- debug=self._debug)
+ self._qmp = qmp.qmp.QEMUMonitorProtocol(self._monitor_address,
+ server=True, debug=self._debug)
def _post_launch(self):
self._qmp.accept()
@@ -131,9 +146,11 @@ class QEMUMachine(object):
qemulog = open(self._qemu_log_path, 'wb')
try:
self._pre_launch()
- args = self._wrapper + [self._binary] + self._base_args() + self._args
+ args = (self._wrapper + [self._binary] + self._base_args() +
+ self._args)
self._popen = subprocess.Popen(args, stdin=devnull, stdout=qemulog,
- stderr=subprocess.STDOUT, shell=False)
+ stderr=subprocess.STDOUT,
+ shell=False)
self._post_launch()
except:
if self.is_running():
@@ -149,28 +166,34 @@ class QEMUMachine(object):
try:
self._qmp.cmd('quit')
self._qmp.close()
- except:
+ except: # kill VM on any failure pylint: disable=W0702
self._popen.kill()
exitcode = self._popen.wait()
if exitcode < 0:
- sys.stderr.write('qemu received signal %i: %s\n' % (-exitcode, ' '.join(self._args)))
+ sys.stderr.write('qemu received signal %i: %s\n'
+ % (-exitcode, ' '.join(self._args)))
self._load_io_log()
self._post_shutdown()
underscore_to_dash = string.maketrans('_', '-')
+
def qmp(self, cmd, conv_keys=True, **args):
'''Invoke a QMP command and return the result dict'''
qmp_args = dict()
- for k in args.keys():
+ for key in args.keys():
if conv_keys:
- qmp_args[k.translate(self.underscore_to_dash)] = args[k]
+ qmp_args[key.translate(self.underscore_to_dash)] = args[key]
else:
- qmp_args[k] = args[k]
+ qmp_args[key] = args[key]
return self._qmp.cmd(cmd, args=qmp_args)
def command(self, cmd, conv_keys=True, **args):
+ '''
+ Invoke a QMP command and on success report result dict or on failure
+ raise exception with details.
+ '''
reply = self.qmp(cmd, conv_keys, **args)
if reply is None:
raise Exception("Monitor is closed")
@@ -193,15 +216,18 @@ class QEMUMachine(object):
return events
def event_wait(self, name, timeout=60.0, match=None):
- # Test if 'match' is a recursive subset of 'event'
- def event_match(event, match=None):
+ ''' Wait for event in QMP, optionally filter results by match. '''
+ # Test if 'match' is a recursive subset of 'event'; skips branch
+ # processing on match's value `None`
+ # {"foo": {"bar": 1} matches {"foo": None}
+ def _event_match(event, match=None):
if match is None:
return True
for key in match:
if key in event:
if isinstance(event[key], dict):
- if not event_match(event[key], match[key]):
+ if not _event_match(event[key], match[key]):
return False
elif event[key] != match[key]:
return False
@@ -212,18 +238,22 @@ class QEMUMachine(object):
# Search cached events
for event in self._events:
- if (event['event'] == name) and event_match(event, match):
+ if (event['event'] == name) and _event_match(event, match):
self._events.remove(event)
return event
# Poll for new events
while True:
event = self._qmp.pull_event(wait=timeout)
- if (event['event'] == name) and event_match(event, match):
+ if (event['event'] == name) and _event_match(event, match):
return event
self._events.append(event)
return None
def get_log(self):
+ '''
+ After self.shutdown or failed qemu execution this returns the output
+ of the qemu process.
+ '''
return self._iolog
--
2.9.4
next prev parent reply other threads:[~2017-07-20 16:38 UTC|newest]
Thread overview: 44+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-07-20 16:28 [Qemu-devel] [PATCH 00/11] qemu.py: Pylint/style fixes Lukáš Doktor
2017-07-20 16:28 ` Lukáš Doktor [this message]
2017-07-21 5:28 ` [Qemu-devel] [PATCH 01/11] " Philipp Hahn
2017-07-20 16:28 ` [Qemu-devel] [PATCH 02/11] qemu.py: Avoid dangerous arguments Lukáš Doktor
2017-07-20 18:19 ` Eduardo Habkost
2017-07-22 1:22 ` Philippe Mathieu-Daudé
2017-07-20 16:28 ` [Qemu-devel] [PATCH 03/11] qemu.py: Use iteritems rather than keys() Lukáš Doktor
2017-07-20 18:19 ` Eduardo Habkost
2017-07-22 1:22 ` Philippe Mathieu-Daudé
2017-07-20 16:28 ` [Qemu-devel] [PATCH 04/11] qemu.py: Simplify QMP key-conversion Lukáš Doktor
2017-07-20 18:20 ` Eduardo Habkost
2017-07-20 16:28 ` [Qemu-devel] [PATCH 05/11] qemu.py: Use custom exceptions rather than Exception Lukáš Doktor
2017-07-20 18:27 ` Eduardo Habkost
2017-07-21 6:37 ` Lukáš Doktor
2017-07-21 18:42 ` Eduardo Habkost
2017-07-24 12:13 ` Lukáš Doktor
2017-07-24 15:32 ` Eduardo Habkost
2017-07-25 5:34 ` Lukáš Doktor
2017-07-20 16:28 ` [Qemu-devel] [PATCH 06/11] qmp.py: Couple of pylint/style fixes Lukáš Doktor
2017-07-22 1:30 ` Philippe Mathieu-Daudé
2017-07-24 12:36 ` Lukáš Doktor
2017-07-25 6:04 ` Philippe Mathieu-Daudé
2017-07-25 6:13 ` Lukáš Doktor
2017-07-25 6:20 ` Philippe Mathieu-Daudé
2017-07-20 16:28 ` [Qemu-devel] [PATCH 07/11] qmp.py: Use object-based class for QEMUMonitorProtocol Lukáš Doktor
2017-07-20 18:35 ` Eduardo Habkost
2017-07-21 6:50 ` Lukáš Doktor
2017-07-21 18:43 ` Eduardo Habkost
2017-07-20 16:28 ` [Qemu-devel] [PATCH 08/11] qmp.py: Avoid "has_key" usage Lukáš Doktor
2017-07-20 18:35 ` Eduardo Habkost
2017-07-22 1:31 ` Philippe Mathieu-Daudé
2017-07-20 16:28 ` [Qemu-devel] [PATCH 09/11] qmp.py: Avoid overriding a builtin object Lukáš Doktor
2017-07-20 18:38 ` Eduardo Habkost
2017-07-21 6:53 ` Lukáš Doktor
2017-07-21 18:46 ` Eduardo Habkost
2017-07-24 12:41 ` Lukáš Doktor
2017-07-20 16:28 ` [Qemu-devel] [PATCH 10/11] qtest.py: Few pylint/style fixes Lukáš Doktor
2017-07-20 18:42 ` Eduardo Habkost
2017-07-21 6:57 ` Lukáš Doktor
2017-07-21 18:56 ` Eduardo Habkost
2017-07-24 12:42 ` Lukáš Doktor
2017-07-20 16:28 ` [Qemu-devel] [PATCH 11/11] qtest.py: Avoid using mutable list as default argument Lukáš Doktor
2017-07-20 18:44 ` Eduardo Habkost
2017-07-21 6:58 ` Lukáš Doktor
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20170720162815.19802-2-ldoktor@redhat.com \
--to=ldoktor@redhat.com \
--cc=apahim@redhat.com \
--cc=armbru@redhat.com \
--cc=ehabkost@redhat.com \
--cc=famz@redhat.com \
--cc=mreitz@redhat.com \
--cc=qemu-devel@nongnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.