浏览代码

tools/qubesd-query: add option to report failure with exit code

Marek Marczykowski-Górecki 7 年之前
父节点
当前提交
43fd1d76e8
共有 2 个文件被更改,包括 31 次插入4 次删除
  1. 6 0
      doc/manpages/qubesd-query.rst
  2. 25 4
      qubes/tools/qubesd_query.py

+ 6 - 0
doc/manpages/qubesd-query.rst

@@ -24,6 +24,12 @@ Options
    Send empty payload. Do not attempt to read anything from standard input, but
    Send empty payload. Do not attempt to read anything from standard input, but
    send the request immediately.
    send the request immediately.
 
 
+.. option:: --fail
+
+   Exit with non-0 exit code when qubesd response is not-OK. By default the tool
+   will exit with 0 when request is successfully delivered to qubesd, regardless
+   of response.
+
 Description
 Description
 -----------
 -----------
 
 

+ 25 - 4
qubes/tools/qubesd_query.py

@@ -25,6 +25,11 @@ parser.add_argument('--empty', '-e',
     action='store_false', default=True,
     action='store_false', default=True,
     help='do not read from stdin and send empty payload')
     help='do not read from stdin and send empty payload')
 
 
+parser.add_argument('--fail',
+    dest='fail',
+    action='store_true',
+    help='Should non-OK qubesd response result in non-zero exit code')
+
 parser.add_argument('src', metavar='SRC',
 parser.add_argument('src', metavar='SRC',
     help='source qube')
     help='source qube')
 parser.add_argument('method', metavar='METHOD',
 parser.add_argument('method', metavar='METHOD',
@@ -42,10 +47,18 @@ def sighandler(loop, signame, coro):
 
 
 @asyncio.coroutine
 @asyncio.coroutine
 def qubesd_client(socket, payload, *args):
 def qubesd_client(socket, payload, *args):
+    '''
+    Connect to qubesd, send request and passthrough response to stdout
+
+    :param socket: path to qubesd socket
+    :param payload: payload of the request
+    :param args: request to qubesd
+    :return:
+    '''
     try:
     try:
         reader, writer = yield from asyncio.open_unix_connection(socket)
         reader, writer = yield from asyncio.open_unix_connection(socket)
     except asyncio.CancelledError:
     except asyncio.CancelledError:
-        return
+        return 1
 
 
     for arg in args:
     for arg in args:
         writer.write(arg.encode('ascii'))
         writer.write(arg.encode('ascii'))
@@ -54,12 +67,16 @@ def qubesd_client(socket, payload, *args):
     writer.write_eof()
     writer.write_eof()
 
 
     try:
     try:
+        header_data = yield from reader.read(1)
+        returncode = int(header_data)
+        sys.stdout.buffer.write(header_data)  # pylint: disable=no-member
         while not reader.at_eof():
         while not reader.at_eof():
             data = yield from reader.read(4096)
             data = yield from reader.read(4096)
             sys.stdout.buffer.write(data)  # pylint: disable=no-member
             sys.stdout.buffer.write(data)  # pylint: disable=no-member
             sys.stdout.flush()
             sys.stdout.flush()
+        return returncode
     except asyncio.CancelledError:
     except asyncio.CancelledError:
-        return
+        return 1
     finally:
     finally:
         writer.close()
         writer.close()
 
 
@@ -79,9 +96,13 @@ def main(args=None):
             sighandler, loop, signame, coro)
             sighandler, loop, signame, coro)
 
 
     try:
     try:
-        loop.run_until_complete(coro)
+        returncode = loop.run_until_complete(coro)
     finally:
     finally:
         loop.close()
         loop.close()
 
 
+    if args.fail:
+        return returncode
+    return 0
+
 if __name__ == '__main__':
 if __name__ == '__main__':
-    main()
+    sys.exit(main())