Exemplo n.º 1
0
  def Recv(self):
    """Try to receive a message from the socket.

    In case we already have messages queued, we just return from the
    queue. Otherwise, we try to read data with a _rwtimeout network
    timeout, and making sure we don't go over 2x_rwtimeout as a global
    limit.

    """
    self._CheckSocket()
    etime = time.time() + self._rwtimeout
    while not self._msgs:
      if time.time() > etime:
        raise errors.TimeoutError("Extended receive timeout")
      while True:
        try:
          data = self.socket.recv(4096)
        except socket.timeout as err:
          raise errors.TimeoutError("Receive timeout: %s" % str(err))
        except socket.error as err:
          if err.args and err.args[0] == errno.EAGAIN:
            continue
          raise
        break
      if not data:
        raise errors.ConnectionClosedError("Connection closed while reading")
      new_msgs = (self._buffer + data).split(constants.LUXI_EOM)
      self._buffer = new_msgs.pop()
      self._msgs.extend(new_msgs)
    return self._msgs.popleft().decode("utf-8")
Exemplo n.º 2
0
 def _Connect(sock, address, timeout, allow_non_master):
   sock.settimeout(timeout)
   try:
     sock.connect(address)
   except socket.timeout as err:
     raise errors.TimeoutError("Connect timed out: %s" % str(err))
   except socket.error as err:
     error_code = err.args[0]
     if error_code in (errno.ENOENT, errno.ECONNREFUSED):
       if not allow_non_master:
         # Verify if we're actually on the master node before trying
         # again.
         ss = ssconf.SimpleStore()
         try:
           master, myself = ssconf.GetMasterAndMyself(ss=ss)
         except ganeti.errors.ConfigurationError:
           raise errors.NoMasterError(address)
         if master != myself:
           raise errors.NoMasterError(address)
       raise utils.RetryAgain()
     elif error_code in (errno.EPERM, errno.EACCES):
       raise errors.PermissionError(address)
     elif error_code == errno.EAGAIN:
       # Server's socket backlog is full at the moment
       raise utils.RetryAgain()
     raise
Exemplo n.º 3
0
    def __init__(self, address, timeouts=None, allow_non_master=None):
        """Constructor for the Client class.

    There are two timeouts used since we might want to wait for a long
    time for a response, but the connect timeout should be lower.

    If not passed, we use the default luxi timeouts from the global
    constants file.

    Note that on reading data, since the timeout applies to an
    invidual receive, it might be that the total duration is longer
    than timeout value passed (we make a hard limit at twice the read
    timeout).

    @type address: socket address
    @param address: address the transport connects to
    @type timeouts: list of ints
    @param timeouts: timeouts to be used on connect and read/write
    @type allow_non_master: bool
    @param allow_non_master: skip checks for the master node on errors

    """
        self.address = address
        if timeouts is None:
            self._ctimeout, self._rwtimeout = DEF_CTMO, DEF_RWTO
        else:
            self._ctimeout, self._rwtimeout = timeouts

        self.socket = None
        self._buffer = ""
        self._msgs = collections.deque()

        try:
            self.socket = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)

            # Try to connect
            try:
                utils.Retry(self._Connect,
                            1.0,
                            self._ctimeout,
                            args=(self.socket, address, self._ctimeout,
                                  allow_non_master))
            except utils.RetryTimeout:
                raise errors.TimeoutError("Connect timed out")

            self.socket.settimeout(self._rwtimeout)
        except (socket.error, errors.NoMasterError):
            if self.socket is not None:
                self.socket.close()
            self.socket = None
            raise
Exemplo n.º 4
0
    def Send(self, msg):
        """Send a message.

    This just sends a message and doesn't wait for the response.

    """
        if constants.LUXI_EOM in msg:
            raise errors.ProtocolError("Message terminator found in payload")

        self._CheckSocket()
        try:
            # TODO: sendall is not guaranteed to send everything
            self.socket.sendall(msg + constants.LUXI_EOM)
        except socket.timeout as err:
            raise errors.TimeoutError("Sending timeout: %s" % str(err))
Exemplo n.º 5
0
    def Recv(self):
        """Try to receive a message from the socket.

    In case we already have messages queued, we just return from the
    queue. Otherwise, we try to read data with a _rwtimeout network
    timeout, and making sure we don't go over 2x_rwtimeout as a global
    limit.

    """
        self._CheckSocket()
        etime = time.time() + self._rwtimeout
        while not self._msgs:
            if time.time() > etime:
                raise errors.TimeoutError("Extended receive timeout")
            while True:
                try:
                    data = self.socket.recv(4096)
                except socket.timeout, err:
                    raise errors.TimeoutError("Receive timeout: %s" % str(err))
                except socket.error, err:
                    if err.args and err.args[0] == errno.EAGAIN:
                        continue
                    raise
                break
Exemplo n.º 6
0
    def __init__(self, address, timeouts=None):
        """Constructor for the Client class.

    Arguments:
      - address: a valid address the the used transport class
      - timeout: a list of timeouts, to be used on connect and read/write

    There are two timeouts used since we might want to wait for a long
    time for a response, but the connect timeout should be lower.

    If not passed, we use a default of 10 and respectively 60 seconds.

    Note that on reading data, since the timeout applies to an
    invidual receive, it might be that the total duration is longer
    than timeout value passed (we make a hard limit at twice the read
    timeout).

    """
        self.address = address
        if timeouts is None:
            self._ctimeout, self._rwtimeout = DEF_CTMO, DEF_RWTO
        else:
            self._ctimeout, self._rwtimeout = timeouts

        self.socket = None
        self._buffer = ""
        self._msgs = collections.deque()

        try:
            self.socket = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)

            # Try to connect
            try:
                utils.Retry(self._Connect,
                            1.0,
                            self._ctimeout,
                            args=(self.socket, address, self._ctimeout))
            except utils.RetryTimeout:
                raise errors.TimeoutError("Connect timed out")

            self.socket.settimeout(self._rwtimeout)
        except (socket.error, errors.NoMasterError):
            if self.socket is not None:
                self.socket.close()
            self.socket = None
            raise
Exemplo n.º 7
0
 def _Connect(sock, address, timeout):
     sock.settimeout(timeout)
     try:
         sock.connect(address)
     except socket.timeout, err:
         raise errors.TimeoutError("Connect timed out: %s" % str(err))