def read(self): """ Wait for a JSON encoded message from the remote side. The basic communication protocol is really simple: 1. First an ASCII encoded integer number is received, terminated by a newline. 2. Second the number of bytes given by step 1 is read and interpreted as a JSON encoded value. This step is not terminated by a newline. That's it :-). :returns: The JSON value decoded to a Python value. :raises: :py:exc:`ProtocolError` when the remote side violates the defined protocol. """ logger.debug("Waiting for message from other side ..") # Wait for a line containing an integer byte count. line = self.raw_readline().strip() if not line.isdigit(): # Complain loudly about protocol errors :-). raise ProtocolError( compact(""" Received invalid input from remote side! I was expecting a byte count, but what I got instead was the line {input}! """, input=repr(line))) else: # First we get a line containing a byte count, then we read # that number of bytes from the remote side and decode it as a # JSON encoded message. num_bytes = int(line, 10) logger.debug("Reading message of %i bytes ..", num_bytes) encoded_value = self.raw_read(num_bytes) try: decoded_value = json.loads(encoded_value) logger.debug("Parsed message: %s", decoded_value) return decoded_value except Exception as e: logger.exception("Failed to parse JSON formatted message!") raise ProtocolError( compact(""" Failed to decode message from remote side as JSON! Tried to decode message {message}. Original error: {error}. """, message=repr(encoded_value), error=str(e)))
def find_character_device(port_name): """ Find the character device for the given port name. :param port_name: The name of the virtio port (a string). :returns: The absolute pathname of a character device (a string). :raises: :py:exc:`Exception` when the character device cannot be found. """ root = '/sys/class/virtio-ports' logger.debug( "Automatically selecting appropriate character device based on %s ..", root) for entry in os.listdir(root): name_file = os.path.join(root, entry, 'name') if os.path.isfile(name_file): with open(name_file) as handle: contents = handle.read().strip() if contents == port_name: character_device = '/dev/%s' % entry logger.debug("Selected character device: %s", character_device) return character_device raise Exception( compact(""" Failed to select the appropriate character device for the port name {name}! This is probably caused by a configuration issue on either the QEMU host or inside the QEMU guest. Please refer to the following web page for help: http://negotiator.readthedocs.org/en/latest/#character-device-detection-fails """, name=repr(port_name)))
def find_character_device(port_name): """ Find the character device for the given port name. :param port_name: The name of the virtio port (a string). :returns: The absolute pathname of a character device (a string). :raises: :py:exc:`Exception` when the character device cannot be found. """ root = '/sys/class/virtio-ports' logger.debug("Automatically selecting appropriate character device based on %s ..", root) for entry in os.listdir(root): name_file = os.path.join(root, entry, 'name') if os.path.isfile(name_file): with open(name_file) as handle: contents = handle.read().strip() if contents == port_name: character_device = '/dev/%s' % entry logger.debug("Selected character device: %s", character_device) return character_device raise Exception(compact(""" Failed to select the appropriate character device for the port name {name}! This is probably caused by a configuration issue on either the QEMU host or inside the QEMU guest. Please refer to the following web page for help: http://negotiator.readthedocs.org/en/latest/#character-device-detection-fails """, name=repr(port_name)))
def read(self): """ Wait for a JSON encoded message from the remote side. The basic communication protocol is really simple: 1. First an ASCII encoded integer number is received, terminated by a newline. 2. Second the number of bytes given by step 1 is read and interpreted as a JSON encoded value. This step is not terminated by a newline. That's it :-). :returns: The JSON value decoded to a Python value. :raises: :exc:`ProtocolError` when the remote side violates the defined protocol. """ logger.debug("Waiting for message from other side ..") # Wait for a line containing an integer byte count. line = self.raw_readline().strip() if not line.isdigit(): # Complain loudly about protocol errors :-). raise ProtocolError(compact(""" Received invalid input from remote side! I was expecting a byte count, but what I got instead was the line {input}! """, input=repr(line))) else: # First we get a line containing a byte count, then we read # that number of bytes from the remote side and decode it as a # JSON encoded message. num_bytes = int(line, 10) logger.debug("Reading message of %i bytes ..", num_bytes) encoded_value = self.raw_read(num_bytes) try: decoded_value = json.loads(encoded_value) logger.debug("Parsed message: %s", decoded_value) return decoded_value except Exception as e: logger.exception("Failed to parse JSON formatted message!") raise ProtocolError(compact(""" Failed to decode message from remote side as JSON! Tried to decode message {message}. Original error: {error}. """, message=repr(encoded_value), error=str(e)))