Ejemplo n.º 1
0
    def connectionMade(self):
        sockFD = self.transport.fileno()
        childFDs = {0: sockFD, 1: sockFD}
        if self.factory.stderrFile:
            childFDs[2] = self.factory.stderrFile.fileno()

        # processes run by inetd expect blocking sockets
        # FIXME: maybe this should be done in process.py?  are other uses of
        #        Process possibly affected by this?
        fdesc.setBlocking(sockFD)
        if childFDs.has_key(2):
            fdesc.setBlocking(childFDs[2])

        service = self.factory.service
        uid = service.user
        gid = service.group

        # don't tell Process to change our UID/GID if it's what we
        # already are
        if uid == os.getuid():
            uid = None
        if gid == os.getgid():
            gid = None

        process.Process(None, service.program, service.programArgs, os.environ,
                        None, None, uid, gid, childFDs)

        reactor.removeReader(self.transport)
        reactor.removeWriter(self.transport)
Ejemplo n.º 2
0
    def connectionMade(self):
        sockFD = self.transport.fileno()
        childFDs = {0: sockFD, 1: sockFD}
        if self.factory.stderrFile:
            childFDs[2] = self.factory.stderrFile.fileno()

        # processes run by inetd expect blocking sockets
        # FIXME: maybe this should be done in process.py?  are other uses of
        #        Process possibly affected by this?
        fdesc.setBlocking(sockFD)
        if childFDs.has_key(2):
            fdesc.setBlocking(childFDs[2])

        service = self.factory.service
        uid = service.user
        gid = service.group

        # don't tell Process to change our UID/GID if it's what we
        # already are
        if uid == os.getuid():
            uid = None
        if gid == os.getgid():
            gid = None

        process.Process(None, service.program, service.programArgs, os.environ,
                        None, None, uid, gid, childFDs)

        reactor.removeReader(self.transport)
        reactor.removeWriter(self.transport)
Ejemplo n.º 3
0
 def test_setBlocking(self):
     """
     L{fdesc.setBlocking} sets a file description to blocking.
     """
     r, w = os.pipe()
     self.addCleanup(os.close, r)
     self.addCleanup(os.close, w)
     fdesc.setNonBlocking(r)
     fdesc.setBlocking(r)
     self.assertFalse(fcntl.fcntl(r, fcntl.F_GETFL) & os.O_NONBLOCK)
Ejemplo n.º 4
0
 def test_setBlocking(self):
     """
     L{fdesc.setBlocking} sets a file description to blocking.
     """
     r, w = os.pipe()
     self.addCleanup(os.close, r)
     self.addCleanup(os.close, w)
     fdesc.setNonBlocking(r)
     fdesc.setBlocking(r)
     self.assertFalse(fcntl.fcntl(r, fcntl.F_GETFL) & os.O_NONBLOCK)
Ejemplo n.º 5
0
    def connectionLost(self, reason):
        """
        See abstract.FileDescriptor.connectionLost.
        """
        # At least on macOS 10.4, exiting while stdout is non-blocking can
        # result in data loss.  For some reason putting the file descriptor
        # back into blocking mode seems to resolve this issue.
        fdesc.setBlocking(self.fd)

        abstract.FileDescriptor.connectionLost(self, reason)
        self.proc.childConnectionLost(self.name, reason)
Ejemplo n.º 6
0
    def connectionLost(self, reason):
        """
        See abstract.FileDescriptor.connectionLost.
        """
        # At least on OS X 10.4, exiting while stdout is non-blocking can
        # result in data loss.  For some reason putting the file descriptor
        # back into blocking mode seems to resolve this issue.
        fdesc.setBlocking(self.fd)

        abstract.FileDescriptor.connectionLost(self, reason)
        self.proc.childConnectionLost(self.name, reason)
Ejemplo n.º 7
0
    def _read_loop(self):
        while True:
            try:
                # I/O routing
                r, w, e = select.select([self.socket, sys.stdin], [], [])

                if self.socket in r:
                    data = self.socket.recv(1024)
                    if data:
                        self._receive(data)
                    else:
                        # Nothing received? End of stream.
                        break

                if sys.stdin in r:
                    # Non blocking read. (Write works better in blocking mode.
                    # Especially on OS X.)
                    fdesc.setNonBlocking(sys.stdin)
                    data = sys.stdin.read(1024)
                    # We read larger chuncks (more than just one byte) in
                    # one go. This is important for meta and arrow keys
                    # which consist of multiple bytes. Many applications
                    # rely on this that they'll receive them together.
                    fdesc.setBlocking(sys.stdin)

                    # If we're finish and 'wait_for_closing' was set. Any key
                    # press will terminate the client.
                    if self.wait_for_closing:
                        break

                    if chr(14) in data:  # Ctrl-N
                        # Tell the server to open a new window.
                        self.socket.sendall(
                            pickle.dumps(('open-new-window', '')))
                    else:
                        self.socket.sendall(pickle.dumps(('_input', data)))

            except socket.error:
                print '\nConnection closed...'
                break
            except Exception as e:
                # SIGWINCH will abort select() call. Just ignore this error
                if e.args and e.args[0] == errno.EINTR:
                    continue
                else:
                    raise
Ejemplo n.º 8
0
    def _read_loop(self):
        while True:
            try:
                # I/O routing
                r, w, e = select.select([ self.socket, sys.stdin ], [], [])

                if self.socket in r:
                    data = self.socket.recv(1024)
                    if data:
                        self._receive(data)
                    else:
                        # Nothing received? End of stream.
                        break

                if sys.stdin in r:
                    # Non blocking read. (Write works better in blocking mode.
                    # Especially on OS X.)
                    fdesc.setNonBlocking(sys.stdin)
                    data = sys.stdin.read(1024)
                        # We read larger chuncks (more than just one byte) in
                        # one go. This is important for meta and arrow keys
                        # which consist of multiple bytes. Many applications
                        # rely on this that they'll receive them together.
                    fdesc.setBlocking(sys.stdin)

                    # If we're finish and 'wait_for_closing' was set. Any key
                    # press will terminate the client.
                    if self.wait_for_closing:
                        break

                    if chr(14) in data: # Ctrl-N
                        # Tell the server to open a new window.
                        self.socket.sendall(pickle.dumps(('open-new-window', '')))
                    else:
                        self.socket.sendall(pickle.dumps(('_input', data)))

            except socket.error:
                print '\nConnection closed...'
                break
            except Exception as e:
                # SIGWINCH will abort select() call. Just ignore this error
                if e.args and e.args[0] == errno.EINTR:
                    continue
                else:
                    raise
Ejemplo n.º 9
0
    def _read_loop(self):
        while True:
            try:
                # I/O routing
                r, w, e = select.select([ self.socket, sys.stdin ], [], [])

                if self.socket in r:
                    data = self.socket.recv(1024)
                    if data:
                        self._receive(data)
                    else:
                        # Nothing received? End of stream.
                        break

                if sys.stdin in r:
                    # Non blocking read. (Write works better in blocking mode.
                    # Especially on OS X.)
                    fdesc.setNonBlocking(sys.stdin)
                    data = sys.stdin.read(1)
                    fdesc.setBlocking(sys.stdin)

                    # If we're finish and 'wait_for_closing' was set. Any key
                    # press will terminate the client.
                    if self.wait_for_closing:
                        break

                    if ord(data) == 14: # Ctrl-N
                        # Tell the server to open a new window.
                        self.socket.sendall(pickle.dumps(('open-new-window', '')))
                    else:
                        self.socket.sendall(pickle.dumps(('_input', data)))

            except socket.error:
                print '\nConnection closed...'
                break
            except Exception as e:
                # SIGWINCH will abort select() call. Just ignore this error
                if e.args and e.args[0] == errno.EINTR:
                    continue
                else:
                    raise
Ejemplo n.º 10
0
 def run(self, stdin=None, stdout=None, stderr=None):
     "Start the task, returning status via <task>.deferred callbacks when the task completes. The keyword arguments stdin, stdout, and stderr may be used to override the ones provided at initialization."
     if stdin is None:
         stdin = getattr(self, 'stdin', None)
     if stdout is None:
         stdout = getattr(self, 'stdout', None)
     if stderr is None:
         stderr = getattr(self, 'stderr', None)
     fd = stdin
     prev = None
     for task in self.args:
         if prev:
             self.run_sub(prev, stdin=fd)
             fd = prev.proc.pipes.pop(1)
             fdesc.setBlocking(fd)
             fd.stopReading()
             fd = fd.fileno()
         prev = task
     if prev:
         self.run_sub(prev, stdin=fd, stdout=stdout, stderr=stderr)
     else:
         self.deferred.callback(None)
Ejemplo n.º 11
0
    def _posix_shell(self, chan, raw=True, initial_input=None):
        """
        Create a loop which redirects sys.stdin/stdout into this channel.
        The loop ends when channel.recv() returns 0.

        Code inspired by the Paramiko interactive demo.
        """
        result = []
        password_sent = False

        # Set terminal in raw mode
        if raw:
            context = raw_mode(self.pty.stdin)
        else:
            context = contextlib.nested()

        assert self.pty.set_ssh_channel_size
        with context:
            # Make channel non blocking.
            chan.settimeout(0.0)

            # When initial input has been given, send this first
            if initial_input:
                time.sleep(
                    0.2
                )  # Wait a very short while for the channel to be initialized, before sending.
                chan.send(initial_input)

            reading_from_stdin = True

            # Read/write loop
            while True:
                # Don't wait for any input when an exit status code has been
                # set already. (But still wait for the output to finish.)
                if chan.status_event.isSet():
                    reading_from_stdin = False

                    # When the channel is closed, and there's nothing to read
                    # anymore. We can return what we got from Paramiko. (Not
                    # sure why this happens. Most of the time, select() still
                    # returns and chan.recv() returns an empty string, but when
                    # read_ready is False, select() doesn't return anymore.)
                    if chan.closed and not chan.in_buffer.read_ready():
                        break

                channels = [self.pty.stdin, chan
                            ] if reading_from_stdin else [chan]
                r, w, e = select(channels, [], [], 1)
                # Note the select-timeout. That is required in order to
                # check for the status_event every second.

                # Receive stream
                if chan in r:
                    try:
                        x = chan.recv(1024)

                        # Received length 0 -> end of stream
                        if len(x) == 0:
                            break

                        # Write received characters to stdout and flush
                        while True:
                            try:
                                self.pty.stdout.write(x)
                                break
                            except IOError as e:
                                # Sometimes, when we have a lot of output, we get here:
                                # IOError: [Errno 11] Resource temporarily unavailable
                                # Just waiting a little, and retrying seems to work.
                                # See also: deployer.run.socket_client for a similar issue.
                                time.sleep(0.2)

                        self.pty.stdout.flush()

                        # Also remember received output.
                        # We want to return what's written to stdout.
                        result.append(x)

                        # Do we need to send the sudo password? (It's when the
                        # magic prompt has been detected in the stream) Note
                        # that we only monitor the last part of 'result', it's
                        # a bit fuzzy, but works.
                        if not password_sent and self.magic_sudo_prompt in ''.join(
                                result[-32:]):
                            chan.send(self.password)
                            chan.send('\n')
                            password_sent = True
                    except socket.timeout:
                        pass

                # Send stream (one by one character)
                # (use 'elif', read stdin only when there is no more output to be received.)
                elif self.pty.stdin in r:
                    try:
                        # Make stdin non-blocking. (The select call already
                        # blocked for us, we want sys.stdin.read() to read
                        # as many bytes as possible without blocking.)
                        try:
                            fdesc.setNonBlocking(self.pty.stdin)
                            x = self.pty.stdin.read(1024)
                        finally:
                            # Set stdin blocking again
                            # (Writing works better in blocking mode.
                            # Especially OS X seems to be very sensitive if we
                            # write lange amounts [>1000 bytes] nonblocking to
                            # stdout. That causes a lot of IOErrors.)
                            fdesc.setBlocking(self.pty.stdin)

                        # We receive \n from stdin, but \r is required to
                        # send. (Until now, the only place where the
                        # difference became clear is in redis-cli, which
                        # only accepts \r as confirmation.)
                        x = x.replace('\n', '\r')
                    except IOError as e:
                        # What to do with IOError exceptions?
                        # (we see what happens in the next select-call.)
                        continue

                    # Received length 0
                    # There's no more at stdin to read.
                    if len(x) == 0:
                        # However, we should go on processing the input
                        # from the remote end, until the process finishes
                        # there (because it was done or processed Ctrl-C or
                        # Ctrl-D/EOF.)
                        #
                        # The end of the input stream happens when we are
                        # using StringIO at the client side, and we're not
                        # attached to a real pseudo terminal. (For
                        # unit-testing, or background commands.)
                        reading_from_stdin = False
                        continue

                    # Write to channel
                    chan.send(x)

                    # Not sure about this. Sometimes, when pasting large data
                    # in the command line, the many concecutive read or write
                    # commands will make Paramiko hang somehow...  (This was
                    # the case, when still using a blocking pty.stdin.read(1)
                    # instead of a non-blocking readmany.
                    time.sleep(0.01)

            return ''.join(result)
Ejemplo n.º 12
0
    def _posix_shell(self, chan, raw=True, initial_input=None):
        """
        Create a loop which redirects sys.stdin/stdout into this channel.
        The loop ends when channel.recv() returns 0.

        Code inspired by the Paramiko interactive demo.
        """
        result = []
        password_sent = False

        # Set terminal in raw mode
        if raw:
            context = raw_mode(self.pty.stdin)
        else:
            context = contextlib.nested()

        assert self.pty.set_ssh_channel_size
        with context:
            # Make channel non blocking.
            chan.settimeout(0.0)

            # When initial input has been given, send this first
            if initial_input:
                time.sleep(0.2) # Wait a very short while for the channel to be initialized, before sending.
                chan.send(initial_input)

            reading_from_stdin = True

            # Read/write loop
            while True:
                # Don't wait for any input when an exit status code has been
                # set already. (But still wait for the output to finish.)
                if chan.status_event.isSet():
                    reading_from_stdin = False

                    # When the channel is closed, and there's nothing to read
                    # anymore. We can return what we got from Paramiko. (Not
                    # sure why this happens. Most of the time, select() still
                    # returns and chan.recv() returns an empty string, but when
                    # read_ready is False, select() doesn't return anymore.)
                    if chan.closed and not chan.in_buffer.read_ready():
                        break

                channels = [self.pty.stdin, chan] if reading_from_stdin else [chan]
                r, w, e = select(channels, [], [], 1)
                    # Note the select-timeout. That is required in order to
                    # check for the status_event every second.

                # Receive stream
                if chan in r:
                    try:
                        x = chan.recv(1024)

                        # Received length 0 -> end of stream
                        if len(x) == 0:
                            break

                        # Write received characters to stdout and flush
                        while True:
                            try:
                                self.pty.stdout.write(x)
                                break
                            except IOError as e:
                                # Sometimes, when we have a lot of output, we get here:
                                # IOError: [Errno 11] Resource temporarily unavailable
                                # Just waiting a little, and retrying seems to work.
                                # See also: deployer.run.socket_client for a similar issue.
                                time.sleep(0.2)

                        self.pty.stdout.flush()

                        # Also remember received output.
                        # We want to return what's written to stdout.
                        result.append(x)

                        # Do we need to send the sudo password? (It's when the
                        # magic prompt has been detected in the stream) Note
                        # that we only monitor the last part of 'result', it's
                        # a bit fuzzy, but works.
                        if not password_sent and self.magic_sudo_prompt in ''.join(result[-32:]):
                            chan.send(self.password)
                            chan.send('\n')
                            password_sent = True
                    except socket.timeout:
                        pass

                # Send stream (one by one character)
                # (use 'elif', read stdin only when there is no more output to be received.)
                elif self.pty.stdin in r:
                    try:
                        # Make stdin non-blocking. (The select call already
                        # blocked for us, we want sys.stdin.read() to read
                        # as many bytes as possible without blocking.)
                        try:
                            fdesc.setNonBlocking(self.pty.stdin)
                            x = self.pty.stdin.read(1024)
                        finally:
                            # Set stdin blocking again
                            # (Writing works better in blocking mode.
                            # Especially OS X seems to be very sensitive if we
                            # write lange amounts [>1000 bytes] nonblocking to
                            # stdout. That causes a lot of IOErrors.)
                            fdesc.setBlocking(self.pty.stdin)

                        # We receive \n from stdin, but \r is required to
                        # send. (Until now, the only place where the
                        # difference became clear is in redis-cli, which
                        # only accepts \r as confirmation.)
                        x = x.replace('\n', '\r')
                    except IOError as e:
                        # What to do with IOError exceptions?
                        # (we see what happens in the next select-call.)
                        continue

                    # Received length 0
                    # There's no more at stdin to read.
                    if len(x) == 0:
                        # However, we should go on processing the input
                        # from the remote end, until the process finishes
                        # there (because it was done or processed Ctrl-C or
                        # Ctrl-D/EOF.)
                        #
                        # The end of the input stream happens when we are
                        # using StringIO at the client side, and we're not
                        # attached to a real pseudo terminal. (For
                        # unit-testing, or background commands.)
                        reading_from_stdin = False
                        continue

                    # Write to channel
                    chan.send(x)

                    # Not sure about this. Sometimes, when pasting large data
                    # in the command line, the many concecutive read or write
                    # commands will make Paramiko hang somehow...  (This was
                    # the case, when still using a blocking pty.stdin.read(1)
                    # instead of a non-blocking readmany.
                    time.sleep(0.01)

            return ''.join(result)
Ejemplo n.º 13
0
	def doRead(self):
		try:
			setBlocking(False,0)
			return fdesc.readFromFD(0, self.dataReceived)
		finally:
			fdesc.setBlocking(True,0)
Ejemplo n.º 14
0
    def _posix_shell(self, pty, chan, raw=True, log_entry=None, initial_input=None):
        """
        Create a loop which redirects sys.stdin/stdout into this channel.
        The loop ends when channel.recv() returns 0.

        Code inspired by the Paramiko interactive demo.
        """
        result = []
        password_sent = False

        # Save terminal attributes
        oldtty = termios.tcgetattr(pty.stdin)

        # Make stdin non-blocking. (The select call will already
        # block for us, we want sys.stdin.read() to read as many
        # bytes as possible without blocking.)
        fdesc.setNonBlocking(pty.stdin)

        try:
            # Set terminal raw
            if raw:
                tty.setraw(pty.stdin.fileno())
                tty.setcbreak(pty.stdin.fileno())
            chan.settimeout(0.0)

            # When initial input has been given, send this first
            if initial_input:
                time.sleep(0.2) # Wait a very short while for the channel to be initialized, before sending.
                chan.send(initial_input)

            # Read/write loop
            while True:
                # Don't wait for any input when an exit status code has been
                # set already.
                if chan.status_event.isSet():
                    break;

                r, w, e = select([pty.stdin, chan], [], [])

                # Receive stream
                if chan in r:
                    try:
                        x = chan.recv(1024)

                        # Received length 0 -> end of stream
                        if len(x) == 0:
                            break

                        # Log received characters
                        log_entry.log_io(x)

                        # Write received characters to stdout and flush
                        pty.stdout.write(x)
                        pty.stdout.flush()

                        # Also remember received output.
                        # We want to return what's written to stdout.
                        result.append(x)

                        # Do we need to send the sudo password? (It's when the
                        # magic prompt has been detected in the stream) Note
                        # that we only monitor the last part of 'result', it's
                        # a bit fuzzy, but works.
                        if not password_sent and self.magic_sudo_prompt in ''.join(result[-32:]):
                            chan.send(self.password)
                            chan.send('\n')
                            password_sent = True
                    except socket.timeout:
                        pass

                # Send stream (one by one character)
                if pty.stdin in r:
                    try:
                        x = pty.stdin.read(1024)
                    except IOError, e:
                        # What to do with IOError exceptions?
                        # (we see what happens in the next select-call.)
                        continue

                    # Received length 0 -> end of stream
                    if len(x) == 0:
                        break

                    # Write to channel
                    chan.send(x)

                    # Not sure about this. Sometimes, when pasting large data
                    # in the command line, the many concecutive read or write
                    # commands will make Paramiko hang somehow...  (This was
                    # the case, when still using a blocking pty.stdin.read(1)
                    # instead of a non-blocking readmany.
                    time.sleep(0.01)
        finally:
            # Restore terminal
            termios.tcsetattr(pty.stdin, termios.TCSADRAIN, oldtty)

        # Set blocking again
        fdesc.setBlocking(pty.stdin)

        return ''.join(result)
Ejemplo n.º 15
0
 def __init__(self, *a, **kw):
     process.ProcessReader.__init__(self, *a, **kw)
     fdesc.setBlocking(sys.stdin.fileno())
Ejemplo n.º 16
0
	def __init__(self,*a,**k):
		super(StdIO,self).__init__(*a,**k)
		fdesc.setBlocking(self._writer.fd)
Ejemplo n.º 17
0
                            # unit-testing, or background commands.)
                            reading_from_stdin = False
                            continue

                        # Write to channel
                        chan.send(x)

                        # Not sure about this. Sometimes, when pasting large data
                        # in the command line, the many concecutive read or write
                        # commands will make Paramiko hang somehow...  (This was
                        # the case, when still using a blocking pty.stdin.read(1)
                        # instead of a non-blocking readmany.
                        time.sleep(0.01)
            finally:
                # Set blocking again
                fdesc.setBlocking(pty.stdin)

            return ''.join(result)

    # =====[ SFTP operations ]====

    def _expand_local_path(self, path):
        # Only tilde expansion
        return os.path.expanduser(path)

    def expand_path(self, path, context=None):
        raise NotImplementedError

    def _tempfile(self, context):
        """ Return temporary filename """
        return self.expand_path('~/deployer-tempfile-%s-%s' % (time.time(), random.randint(0, 1000000)), context)
Ejemplo n.º 18
0
                    # Write to channel
                    chan.send(x)

                    # Not sure about this. Sometimes, when pasting large data
                    # in the command line, the many concecutive read or write
                    # commands will make Paramiko hang somehow...  (This was
                    # the case, when still using a blocking pty.stdin.read(1)
                    # instead of a non-blocking readmany.
                    time.sleep(0.01)
        finally:
            # Restore terminal
            termios.tcsetattr(pty.stdin, termios.TCSADRAIN, oldtty)

            # Set blocking again
            fdesc.setBlocking(pty.stdin)

        return ''.join(result)

    # =====[ Actions which are also available in non-sandbox mode ]====

    def get_ip_address(self, interface='eth0'):
        """
        Return internal IP address of this interface.
        """
        # Add "cd /", to be sure that at least no error get thrown because
        # we're in a non existing directory right now.
        with self.cd('/'):
            with self.sandbox(False):
                # Some hosts give 'inet addr:', other 'enet adr:' back.
                #