Exemple #1
0
def request(status_file: str, command: str, *, timeout: Optional[int] = None,
            **kwds: object) -> Dict[str, Any]:
    """Send a request to the daemon.

    Return the JSON dict with the response.

    Raise BadStatus if there is something wrong with the status file
    or if the process whose pid is in the status file has died.

    Return {'error': <message>} if an IPC operation or receive()
    raised OSError.  This covers cases such as connection refused or
    closed prematurely as well as invalid JSON received.
    """
    response = {}  # type: Dict[str, str]
    args = dict(kwds)
    args['command'] = command
    # Tell the server whether this request was initiated from a human-facing terminal,
    # so that it can format the type checking output accordingly.
    args['is_tty'] = sys.stdout.isatty()
    args['terminal_width'] = get_terminal_width()
    bdata = json.dumps(args).encode('utf8')
    _, name = get_status(status_file)
    try:
        with IPCClient(name, timeout) as client:
            client.write(bdata)
            response = receive(client)
    except (OSError, IPCException) as err:
        return {'error': str(err)}
    # TODO: Other errors, e.g. ValueError, UnicodeError
    else:
        return response
Exemple #2
0
def request(command: str,
            *,
            timeout: Optional[float] = None,
            **kwds: object) -> Dict[str, Any]:
    """Send a request to the daemon.

    Return the JSON dict with the response.

    Raise BadStatus if there is something wrong with the status file
    or if the process whose pid is in the status file has died.

    Return {'error': <message>} if a socket operation or receive()
    raised OSError.  This covers cases such as connection refused or
    closed prematurely as well as invalid JSON received.
    """
    args = dict(kwds)
    args.update(command=command)
    bdata = json.dumps(args).encode('utf8')
    pid, sockname = get_status()
    sock = socket.socket(socket.AF_UNIX)
    if timeout is not None:
        sock.settimeout(timeout)
    try:
        sock.connect(sockname)
        sock.sendall(bdata)
        sock.shutdown(socket.SHUT_WR)
        response = receive(sock)
    except OSError as err:
        return {'error': str(err)}
    # TODO: Other errors, e.g. ValueError, UnicodeError
    else:
        return response
    finally:
        sock.close()
Exemple #3
0
def request(status_file: str,
            command: str,
            *,
            timeout: Optional[int] = None,
            **kwds: object) -> Dict[str, Any]:
    """Send a request to the daemon.

    Return the JSON dict with the response.

    Raise BadStatus if there is something wrong with the status file
    or if the process whose pid is in the status file has died.

    Return {'error': <message>} if an IPC operation or receive()
    raised OSError.  This covers cases such as connection refused or
    closed prematurely as well as invalid JSON received.
    """
    response = {}  # type: Dict[str, str]
    args = dict(kwds)
    args.update(command=command)
    bdata = json.dumps(args).encode('utf8')
    _, name = get_status(status_file)
    try:
        with IPCClient(name, timeout) as client:
            client.write(bdata)
            response = receive(client)
    except (OSError, IPCException) as err:
        return {'error': str(err)}
    # TODO: Other errors, e.g. ValueError, UnicodeError
    else:
        return response
Exemple #4
0
def request(status_file: str, command: str, *, timeout: Optional[int] = None,
            **kwds: object) -> Dict[str, Any]:
    """Send a request to the daemon.

    Return the JSON dict with the response.

    Raise BadStatus if there is something wrong with the status file
    or if the process whose pid is in the status file has died.

    Return {'error': <message>} if an IPC operation or receive()
    raised OSError.  This covers cases such as connection refused or
    closed prematurely as well as invalid JSON received.
    """
    response = {}  # type: Dict[str, str]
    args = dict(kwds)
    args.update(command=command)
    bdata = json.dumps(args).encode('utf8')
    _, name = get_status(status_file)
    try:
        with IPCClient(name, timeout) as client:
            client.write(bdata)
            response = receive(client)
    except (OSError, IPCException) as err:
        return {'error': str(err)}
    # TODO: Other errors, e.g. ValueError, UnicodeError
    else:
        return response
Exemple #5
0
 def serve(self) -> None:
     """Serve requests, synchronously (no thread or fork)."""
     try:
         sock = self.create_listening_socket()
         if self.timeout is not None:
             sock.settimeout(self.timeout)
         try:
             with open(STATUS_FILE, 'w') as f:
                 json.dump(
                     {
                         'pid': os.getpid(),
                         'sockname': sock.getsockname()
                     }, f)
                 f.write('\n')  # I like my JSON with trailing newline
             while True:
                 try:
                     conn, addr = sock.accept()
                 except socket.timeout:
                     print("Exiting due to inactivity.")
                     self.free_global_state()
                     sys.exit(0)
                 try:
                     data = receive(conn)
                 except OSError as err:
                     conn.close()  # Maybe the client hung up
                     continue
                 resp = {}  # type: Dict[str, Any]
                 if 'command' not in data:
                     resp = {'error': "No command found in request"}
                 else:
                     command = data['command']
                     if not isinstance(command, str):
                         resp = {'error': "Command is not a string"}
                     else:
                         command = data.pop('command')
                     try:
                         resp = self.run_command(command, data)
                     except Exception:
                         # If we are crashing, report the crash to the client
                         tb = traceback.format_exception(
                             *sys.exc_info())  # type: ignore
                         resp = {'error': "Daemon crashed!\n" + "".join(tb)}
                         conn.sendall(json.dumps(resp).encode('utf8'))
                         raise
                 try:
                     conn.sendall(json.dumps(resp).encode('utf8'))
                 except OSError as err:
                     pass  # Maybe the client hung up
                 conn.close()
                 if command == 'stop':
                     sock.close()
                     self.free_global_state()
                     sys.exit(0)
         finally:
             os.unlink(STATUS_FILE)
     finally:
         os.unlink(self.sockname)
         exc_info = sys.exc_info()
         if exc_info[0] and exc_info[0] is not SystemExit:
             traceback.print_exception(*exc_info)  # type: ignore
Exemple #6
0
def request(command: str, *, timeout: Optional[float] = None,
            **kwds: object) -> Dict[str, Any]:
    """Send a request to the daemon.

    Return the JSON dict with the response.

    Raise BadStatus if there is something wrong with the status file
    or if the process whose pid is in the status file has died.

    Return {'error': <message>} if a socket operation or receive()
    raised OSError.  This covers cases such as connection refused or
    closed prematurely as well as invalid JSON received.
    """
    args = dict(kwds)
    args.update(command=command)
    bdata = json.dumps(args).encode('utf8')
    pid, sockname = get_status()
    sock = socket.socket(socket.AF_UNIX)
    if timeout is not None:
        sock.settimeout(timeout)
    try:
        sock.connect(sockname)
        sock.sendall(bdata)
        sock.shutdown(socket.SHUT_WR)
        response = receive(sock)
    except OSError as err:
        return {'error': str(err)}
    # TODO: Other errors, e.g. ValueError, UnicodeError
    else:
        return response
    finally:
        sock.close()
Exemple #7
0
 def serve(self) -> None:
     """Serve requests, synchronously (no thread or fork)."""
     try:
         sock = self.create_listening_socket()
         try:
             with open(STATUS_FILE, 'w') as f:
                 json.dump({'pid': os.getpid(), 'sockname': sock.getsockname()}, f)
                 f.write('\n')  # I like my JSON with trailing newline
             while True:
                 conn, addr = sock.accept()
                 data = receive(conn)
                 resp = {}  # type: Dict[str, Any]
                 if 'command' not in data:
                     resp = {'error': "No command found in request"}
                 else:
                     command = data['command']
                     if not isinstance(command, str):
                         resp = {'error': "Command is not a string"}
                     else:
                         command = data.pop('command')
                     resp = self.run_command(command, data)
                 try:
                     conn.sendall(json.dumps(resp).encode('utf8'))
                 except OSError as err:
                     pass  # Maybe the client hung up
                 conn.close()
                 if command == 'stop':
                     sock.close()
                     sys.exit(0)
         finally:
             os.unlink(STATUS_FILE)
     finally:
         os.unlink(self.sockname)
Exemple #8
0
 def serve(self) -> None:
     """Serve requests, synchronously (no thread or fork)."""
     command = None
     try:
         server = IPCServer(CONNECTION_NAME, self.timeout)
         with open(self.status_file, 'w') as f:
             json.dump(
                 {
                     'pid': os.getpid(),
                     'connection_name': server.connection_name
                 }, f)
             f.write('\n')  # I like my JSON with a trailing newline
         while True:
             with server:
                 data = receive(server)
                 resp = {}  # type: Dict[str, Any]
                 if 'command' not in data:
                     resp = {'error': "No command found in request"}
                 else:
                     command = data['command']
                     if not isinstance(command, str):
                         resp = {'error': "Command is not a string"}
                     else:
                         command = data.pop('command')
                         try:
                             resp = self.run_command(command, data)
                         except Exception:
                             # If we are crashing, report the crash to the client
                             tb = traceback.format_exception(
                                 *sys.exc_info())
                             resp = {
                                 'error': "Daemon crashed!\n" + "".join(tb)
                             }
                             resp.update(self._response_metadata())
                             server.write(json.dumps(resp).encode('utf8'))
                             raise
                 try:
                     resp.update(self._response_metadata())
                     server.write(json.dumps(resp).encode('utf8'))
                 except OSError:
                     pass  # Maybe the client hung up
                 if command == 'stop':
                     reset_global_state()
                     sys.exit(0)
     finally:
         # If the final command is something other than a clean
         # stop, remove the status file. (We can't just
         # simplify the logic and always remove the file, since
         # that could cause us to remove a future server's
         # status file.)
         if command != 'stop':
             os.unlink(self.status_file)
         try:
             server.cleanup()  # try to remove the socket dir on Linux
         except OSError:
             pass
         exc_info = sys.exc_info()
         if exc_info[0] and exc_info[0] is not SystemExit:
             traceback.print_exception(*exc_info)
Exemple #9
0
 def serve(self) -> None:
     """Serve requests, synchronously (no thread or fork)."""
     try:
         sock = self.create_listening_socket()
         if self.timeout is not None:
             sock.settimeout(self.timeout)
         try:
             with open(STATUS_FILE, 'w') as f:
                 json.dump({'pid': os.getpid(), 'sockname': sock.getsockname()}, f)
                 f.write('\n')  # I like my JSON with trailing newline
             while True:
                 try:
                     conn, addr = sock.accept()
                 except socket.timeout:
                     print("Exiting due to inactivity.")
                     sys.exit(0)
                 try:
                     data = receive(conn)
                 except OSError as err:
                     conn.close()  # Maybe the client hung up
                     continue
                 resp = {}  # type: Dict[str, Any]
                 if 'command' not in data:
                     resp = {'error': "No command found in request"}
                 else:
                     command = data['command']
                     if not isinstance(command, str):
                         resp = {'error': "Command is not a string"}
                     else:
                         command = data.pop('command')
                     try:
                         resp = self.run_command(command, data)
                     except Exception:
                         # If we are crashing, report the crash to the client
                         tb = traceback.format_exception(*sys.exc_info())  # type: ignore
                         resp = {'error': "Daemon crashed!\n" + "".join(tb)}
                         conn.sendall(json.dumps(resp).encode('utf8'))
                         raise
                 try:
                     conn.sendall(json.dumps(resp).encode('utf8'))
                 except OSError as err:
                     pass  # Maybe the client hung up
                 conn.close()
                 if command == 'stop':
                     sock.close()
                     sys.exit(0)
         finally:
             os.unlink(STATUS_FILE)
     finally:
         os.unlink(self.sockname)
         exc_info = sys.exc_info()
         if exc_info[0] and exc_info[0] is not SystemExit:
             traceback.print_exception(*exc_info)  # type: ignore
Exemple #10
0
 def serve(self) -> None:
     """Serve requests, synchronously (no thread or fork)."""
     command = None
     try:
         server = IPCServer(CONNECTION_NAME, self.timeout)
         with open(self.status_file, 'w') as f:
             json.dump({'pid': os.getpid(), 'connection_name': server.connection_name}, f)
             f.write('\n')  # I like my JSON with a trailing newline
         while True:
             with server:
                 data = receive(server)
                 resp = {}  # type: Dict[str, Any]
                 if 'command' not in data:
                     resp = {'error': "No command found in request"}
                 else:
                     command = data['command']
                     if not isinstance(command, str):
                         resp = {'error': "Command is not a string"}
                     else:
                         command = data.pop('command')
                         try:
                             resp = self.run_command(command, data)
                         except Exception:
                             # If we are crashing, report the crash to the client
                             tb = traceback.format_exception(*sys.exc_info())
                             resp = {'error': "Daemon crashed!\n" + "".join(tb)}
                             resp.update(self._response_metadata())
                             server.write(json.dumps(resp).encode('utf8'))
                             raise
                 try:
                     resp.update(self._response_metadata())
                     server.write(json.dumps(resp).encode('utf8'))
                 except OSError:
                     pass  # Maybe the client hung up
                 if command == 'stop':
                     reset_global_state()
                     sys.exit(0)
     finally:
         # If the final command is something other than a clean
         # stop, remove the status file. (We can't just
         # simplify the logic and always remove the file, since
         # that could cause us to remove a future server's
         # status file.)
         if command != 'stop':
             os.unlink(self.status_file)
         try:
             server.cleanup()  # try to remove the socket dir on Linux
         except OSError:
             pass
         exc_info = sys.exc_info()
         if exc_info[0] and exc_info[0] is not SystemExit:
             traceback.print_exception(*exc_info)
Exemple #11
0
 def serve(self) -> None:
     """Serve requests, synchronously (no thread or fork)."""
     try:
         sock = self.create_listening_socket()
         try:
             with open(STATUS_FILE, 'w') as f:
                 json.dump(
                     {
                         'pid': os.getpid(),
                         'sockname': sock.getsockname()
                     }, f)
                 f.write('\n')  # I like my JSON with trailing newline
             while True:
                 conn, addr = sock.accept()
                 data = receive(conn)
                 resp = {}  # type: Dict[str, Any]
                 if 'command' not in data:
                     resp = {'error': "No command found in request"}
                 else:
                     command = data['command']
                     if not isinstance(command, str):
                         resp = {'error': "Command is not a string"}
                     else:
                         command = data.pop('command')
                     resp = self.run_command(command, data)
                 try:
                     conn.sendall(json.dumps(resp).encode('utf8'))
                 except OSError as err:
                     pass  # Maybe the client hung up
                 conn.close()
                 if command == 'stop':
                     sock.close()
                     sys.exit(0)
         finally:
             os.unlink(STATUS_FILE)
     finally:
         os.unlink(self.sockname)
         exc_info = sys.exc_info()
         if exc_info[0]:
             traceback.print_exception(*exc_info)  # type: ignore
Exemple #12
0
def request(command: str, **kwds: object) -> Dict[str, Any]:
    """Send a request to the daemon.

    Return the JSON dict with the response.
    """
    args = dict(kwds)
    if command:
        args.update(command=command)
    data = json.dumps(args)
    pid, sockname = get_status()
    sock = socket.socket(socket.AF_UNIX)
    sock.connect(sockname)
    sock.sendall(data.encode('utf8'))
    sock.shutdown(socket.SHUT_WR)
    try:
        response = receive(sock)
    except OSError as err:
        return {'error': str(err)}
    else:
        return response
    finally:
        sock.close()