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
class Transport: """Low-level transport class. This is used on the client side. This could be replaced by any other class that provides the same semantics to the Client. This means: - can send messages and receive messages - safe for multithreading """ 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 @staticmethod 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)) except socket.error, err: error_code = err.args[0] if error_code in (errno.ENOENT, errno.ECONNREFUSED): # Verify if we're acutally 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