mgmt: add support for events-sending methods
Standard methods return only one value, after operation is completed, but events-related methods may return multiple values during the method execution time. Provide a callback for such cases. Also, according to specification, avoid sending both event and non-event values. QubesOS/qubes-issues#2622
This commit is contained in:
parent
bd9f1d2e7c
commit
40a86efd66
@ -96,7 +96,7 @@ class AbstractQubesMgmt(object):
|
||||
There are also two helper functions for firing events associated with API
|
||||
calls.
|
||||
'''
|
||||
def __init__(self, app, src, method, dest, arg):
|
||||
def __init__(self, app, src, method, dest, arg, send_event=None):
|
||||
#: :py:class:`qubes.Qubes` object
|
||||
self.app = app
|
||||
|
||||
@ -112,6 +112,9 @@ class AbstractQubesMgmt(object):
|
||||
#: name of the method
|
||||
self.method = method.decode('ascii')
|
||||
|
||||
#: callback for sending events if applicable
|
||||
self.send_event = send_event
|
||||
|
||||
#: is this operation cancellable?
|
||||
self.cancellable = False
|
||||
|
||||
|
@ -32,6 +32,7 @@ class QubesDaemonProtocol(asyncio.Protocol):
|
||||
self.len_untrusted_buffer = 0
|
||||
self.transport = None
|
||||
self.debug = debug
|
||||
self.event_sent = False
|
||||
self.mgmt = None
|
||||
|
||||
def connection_made(self, transport):
|
||||
@ -81,6 +82,7 @@ class QubesDaemonProtocol(asyncio.Protocol):
|
||||
self.send_event)
|
||||
response = yield from self.mgmt.execute(
|
||||
untrusted_payload=untrusted_payload)
|
||||
assert not (self.event_sent and response)
|
||||
if self.transport is None:
|
||||
return
|
||||
|
||||
@ -116,6 +118,7 @@ class QubesDaemonProtocol(asyncio.Protocol):
|
||||
src, method, dest, arg, len(untrusted_payload))
|
||||
|
||||
else:
|
||||
if not self.event_sent:
|
||||
self.send_response(response)
|
||||
try:
|
||||
self.transport.write_eof()
|
||||
@ -133,11 +136,13 @@ class QubesDaemonProtocol(asyncio.Protocol):
|
||||
self.transport.write(self.header.pack(*args))
|
||||
|
||||
def send_response(self, content):
|
||||
assert not self.event_sent
|
||||
self.send_header(0x30)
|
||||
if content is not None:
|
||||
self.transport.write(content.encode('utf-8'))
|
||||
|
||||
def send_event(self, subject, event, **kwargs):
|
||||
self.event_sent = True
|
||||
self.send_header(0x31)
|
||||
|
||||
if subject is not self.app:
|
||||
|
Loading…
Reference in New Issue
Block a user