def test_basic_io(self):
     p1, p2 = PipeStream.create_pair()
     p1.write(BYTES_LITERAL("hello"))
     assert p2.poll(0)
     assert p2.read(5) == BYTES_LITERAL("hello")
     assert not p2.poll(0)
     p2.write(BYTES_LITERAL("world"))
     assert p1.poll(0)
     assert p1.read(5) == BYTES_LITERAL("world")
     assert not p1.poll(0)
     p1.close()
     p2.close()
Beispiel #2
0
    def __init__(self,
                 remote_machine,
                 server_class="rpyc.utils.server.ThreadedServer",
                 extra_setup="",
                 python_executable=None):
        self.proc = None
        self.tun = None
        self.remote_machine = remote_machine
        self._tmpdir_ctx = None

        rpyc_root = local.path(rpyc.__file__).up()
        self._tmpdir_ctx = remote_machine.tempdir()
        tmp = self._tmpdir_ctx.__enter__()
        copy(rpyc_root, tmp / "rpyc")

        script = (tmp / "deployed-rpyc.py")
        modname, clsname = server_class.rsplit(".", 1)
        script.write(
            SERVER_SCRIPT.replace("$MODULE$", modname).replace(
                "$SERVER$", clsname).replace("$EXTRA_SETUP$", extra_setup))
        if python_executable:
            cmd = remote_machine[python_executable]
        else:
            major = sys.version_info[0]
            minor = sys.version_info[1]
            cmd = None
            for opt in [
                    "python%s.%s" % (major, minor),
                    "python%s" % (major, )
            ]:
                try:
                    cmd = remote_machine[opt]
                except CommandNotFound:
                    pass
                else:
                    break
            if not cmd:
                cmd = remote_machine.python

        self.proc = cmd.popen(script, new_session=True)

        line = ""
        try:
            line = self.proc.stdout.readline()
            self.remote_port = int(line.strip())
        except Exception:
            try:
                self.proc.terminate()
            except Exception:
                pass
            stdout, stderr = self.proc.communicate()
            raise ProcessExecutionError(self.proc.argv, self.proc.returncode,
                                        BYTES_LITERAL(line) + stdout, stderr)

        if hasattr(remote_machine, "connect_sock"):
            # Paramiko: use connect_sock() instead of tunnels
            self.local_port = None
        else:
            self.local_port = rpyc.utils.factory._get_free_port()
            self.tun = remote_machine.tunnel(self.local_port, self.remote_port)
Beispiel #3
0
    def __init__(self,
                 host,
                 user,
                 keyfile,
                 python_executable='~/anaconda3/bin/python'):

        self.remote_machine = _get_machine(host, user, keyfile)
        self._kill_py()
        self.py = self.remote_machine[python_executable]

        self.proc = self.py.popen(['-m', 'bnb.remote.server'],
                                  new_session=True)
        self.local_port = None

        line = ""
        try:
            logger.debug(f'Waiting for the line')

            line = self.proc.stdout.readline()
            self.remote_port = int(line.strip())

        except Exception:
            stdout, stderr = self.proc.communicate()
            self.close()

            raise ProcessExecutionError(self.proc.argv, self.proc.returncode,
                                        BYTES_LITERAL(line) + stdout, stderr)
Beispiel #4
0
 def read(self, count):
     try:
         if self.poll_read:
             win32file.GetOverlappedResult(self.incoming, self.read_overlapped, 1)
             data = [self.poll_buffer[:]]
             self.poll_read = False
             count -= 1
         else:
             data = []
         while count > 0:
             hr, buf = win32file.ReadFile(self.incoming,
                                          win32file.AllocateReadBuffer(int(min(self.MAX_IO_CHUNK, count))),
                                          self.read_overlapped)
             n = win32file.GetOverlappedResult(self.incoming, self.read_overlapped, 1)
             count -= n
             data.append(buf[:n])
     except TypeError:
         ex = sys.exc_info()[1]
         if not self.closed:
             raise
         raise EOFError(ex)
     except win32file.error:
         ex = sys.exc_info()[1]
         self.close()
         raise EOFError(ex)
     return BYTES_LITERAL("").join(data)
Beispiel #5
0
 def _poll_read(self, timeout=None):
     if not self.client_side:
         return self.upstream.wait(timeout)
     self.sock.settimeout(timeout)
     try:
         buf, addr = self.sock.recvfrom(self.MAX_IO_CHUNK)
     except socket.timeout:
         self.total_timeout += timeout
         if self.total_timeout > 300:
             self.sock.close(
             )  # too much inactivity, disconnect to let it reconnect
         return False
     except socket.error:
         ex = sys.exc_info()[1]
         if get_exc_errno(ex) in (errno.EAGAIN, errno.EWOULDBLOCK):
             # windows just has to be a b**ch
             return True
         self.close()
         raise EOFError(ex)
     if not buf:
         self.close()
         raise EOFError("connection closed by peer")
     self.buf_in.write(BYTES_LITERAL(buf))
     self.total_timeout = 0
     return True
Beispiel #6
0
def _dump_int(obj, stream):
    if obj in IMM_INTS:
        stream.append(IMM_INTS[obj])
    else:
        obj = BYTES_LITERAL(str(obj))
        lenobj = len(obj)
        if lenobj < 256:
            stream.append(TAG_INT_L1 + I1.pack(lenobj) + obj)
        else:
            stream.append(TAG_INT_L4 + I4.pack(lenobj) + obj)
Beispiel #7
0
def dump(obj):
    """Converts (dumps) the given object to a byte-string representation
    
    :param obj: any :func:`dumpable` object
    
    :returns: a byte-string representation of the object
    """
    stream = []
    _dump(obj, stream)
    return BYTES_LITERAL("").join(stream)
 def close(self):
     """closes (terminates) the SSH tunnel"""
     if not self.is_open():
         return
     self.proc.stdin.write(BYTES_LITERAL("foo\n\n\n"))
     self.proc.stdin.close()
     self.proc.stdout.close()
     self.proc.stderr.close()
     try:
         self.proc.kill()
     except AttributeError:
         os.kill(self.proc.pid, signal.SIGTERM)
     self.proc.wait()
     self.proc = None
Beispiel #9
0
 def __init__(self, sshctx, loc_host, loc_port, rem_host, rem_port):
     self.loc_host = loc_host
     self.loc_port = loc_port
     self.rem_host = rem_host
     self.rem_port = rem_port
     self.sshctx = sshctx
     self.proc = sshctx.popen("python",
                              "-u",
                              "-c",
                              self.PROGRAM,
                              L="[%s]:%s:[%s]:%s" %
                              (loc_host, loc_port, rem_host, rem_port))
     banner = self.proc.stdout.readline().strip()
     if banner != BYTES_LITERAL("ready"):
         raise ValueError("tunnel failed", banner)
Beispiel #10
0
    def test_unicode(self):
        self.conn.modules.sys.path.append(u"../你好")
        self.assertEqual(self.conn.modules.sys.path.pop(-1), u"../你好")
        #
        self.conn.execute("x = '111'")
        self.assertEqual(self.conn.namespace["x"], '111')

        self.conn.execute(u"x = u'你好'")
        print(self.conn.eval("type(x)"))
        self.assertEqual(self.conn.namespace["x"], u'你好')

        from rpyc.lib.compat import BYTES_LITERAL
        self.conn.execute("x = u'你好'.encode('utf-8')")
        print(self.conn.eval("type(x)"))
        self.assertEqual(self.conn.namespace["x"], BYTES_LITERAL('你好'))
Beispiel #11
0
 def _read(self):
     try:
         buf = self.sock.recv(self.MAX_IO_CHUNK)
     except socket.timeout:
         return
     except socket.error:
         ex = sys.exc_info()[1]
         if get_exc_errno(ex) in retry_errnos:
             # windows just has to be a bitch
             return
         self.close()
         raise EOFError(ex)
     if not buf:
         self.close()
         raise EOFError("connection closed by peer")
     self.buf_in.write(BYTES_LITERAL(buf))
Beispiel #12
0
 def read(self, count):
     try:
         data = []
         while count > 0:
             dummy, buf = win32file.ReadFile(self.incoming, int(min(self.MAX_IO_CHUNK, count)))
             count -= len(buf)
             data.append(buf)
     except TypeError:
         ex = sys.exc_info()[1]
         if not self.closed:
             raise
         raise EOFError(ex)
     except win32file.error:
         ex = sys.exc_info()[1]
         self.close()
         raise EOFError(ex)
     return BYTES_LITERAL("").join(data)
Beispiel #13
0
 def read(self, count):
     data = []
     try:
         while count > 0:
             buf = os.read(self.incoming.fileno(), min(self.MAX_IO_CHUNK, count))
             if not buf:
                 raise EOFError("connection closed by peer")
             data.append(buf)
             count -= len(buf)
     except EOFError:
         self.close()
         raise
     except EnvironmentError:
         ex = sys.exc_info()[1]
         self.close()
         raise EOFError(ex)
     return BYTES_LITERAL("").join(data)
 def _read(self):
     try:
         buf = self.sock.recv(self.MAX_IO_CHUNK)
     except socket.timeout:
         return
     except socket.error:
         ex = sys.exc_info()[1]
         if get_exc_errno(ex) in (errno.EAGAIN, errno.EWOULDBLOCK):
             # windows just has to be a b**ch
             # edit: some politeness please ;)
             return
         self.close()
         raise EOFError(ex)
     if not buf:
         self.close()
         raise EOFError("connection closed by peer")
     self.buf_in.write(BYTES_LITERAL(buf))
Beispiel #15
0
 def read(self, count):
     data = []
     while count > 0:
         try:
             buf = self.sock.recv(min(self.MAX_IO_CHUNK, count))
         except socket.timeout:
             continue
         except socket.error:
             ex = sys.exc_info()[1]
             if get_exc_errno(ex) in retry_errnos:
                 # windows just has to be a bitch
                 continue
             self.close()
             raise EOFError(ex)
         if not buf:
             self.close()
             raise EOFError("connection closed by peer")
         data.append(buf)
         count -= len(buf)
     return BYTES_LITERAL("").join(data)
Beispiel #16
0
class Channel(object):
    """Channel implementation.
    
    Note: In order to avoid problems with all sorts of line-buffered transports, 
    we deliberately add ``\\n`` at the end of each frame.
    """

    COMPRESSION_THRESHOLD = 3000
    COMPRESSION_LEVEL = 1
    FRAME_HEADER = Struct("!LB")
    FLUSHER = BYTES_LITERAL(
        "\n")  # cause any line-buffered layers below us to flush
    __slots__ = ["stream", "compress"]

    def __init__(self, stream, compress=True):
        self.stream = stream
        if not zlib:
            compress = False
        self.compress = compress

    def close(self):
        """closes the channel and underlying stream"""
        self.stream.close()

    @property
    def closed(self):
        """indicates whether the underlying stream has been closed"""
        return self.stream.closed

    def fileno(self):
        """returns the file descriptor of the underlying stream"""
        return self.stream.fileno()

    def poll(self, timeout):
        """polls the underlying steam for data, waiting up to *timeout* seconds"""
        return self.stream.poll(timeout)

    def recv(self):
        """Receives the next packet (or *frame*) from the underlying stream.
        This method will block until the packet has been read completely
        
        :returns: string of data
        """
        header = self.stream.read(self.FRAME_HEADER.size)
        length, compressed = self.FRAME_HEADER.unpack(header)
        data = self.stream.read(length +
                                len(self.FLUSHER))[:-len(self.FLUSHER)]
        if compressed:
            data = zlib.decompress(data)
        return data

    def send(self, data):
        """Sends the given string of data as a packet over the underlying 
        stream. Blocks until the packet has been sent.
        
        :param data: the byte string to send as a packet
        """
        if self.compress and len(data) > self.COMPRESSION_THRESHOLD:
            compressed = 1
            data = zlib.compress(data, self.COMPRESSION_LEVEL)
        else:
            compressed = 0
        header = self.FRAME_HEADER.pack(len(data), compressed)
        buf = header + data + self.FLUSHER
        self.stream.write(buf)
Beispiel #17
0
 def _load_empty_str(stream):
     return BYTES_LITERAL("")
Beispiel #18
0
    >>> x = ("he", 7, u"llo", 8, (), 900, None, True, Ellipsis, 18.2, 18.2j + 13,
    ... slice(1,2,3), frozenset([5,6,7]), NotImplemented)
    >>> dumpable(x)
    True
    >>> y = dump(x)
    >>> y.encode("hex")
    '140e0b686557080c6c6c6f580216033930300003061840323333333333331b402a000000000000403233333333333319125152531a1255565705'
    >>> z = load(y)
    >>> x == z
    True
"""
from rpyc.lib.compat import Struct, BytesIO, is_py3k, BYTES_LITERAL

# singletons
TAG_NONE = BYTES_LITERAL("\x00")
TAG_EMPTY_STR = BYTES_LITERAL("\x01")
TAG_EMPTY_TUPLE = BYTES_LITERAL("\x02")
TAG_TRUE = BYTES_LITERAL("\x03")
TAG_FALSE = BYTES_LITERAL("\x04")
TAG_NOT_IMPLEMENTED = BYTES_LITERAL("\x05")
TAG_ELLIPSIS = BYTES_LITERAL("\x06")
# types
TAG_UNICODE = BYTES_LITERAL("\x08")
TAG_LONG = BYTES_LITERAL("\x09")
TAG_STR1 = BYTES_LITERAL("\x0a")
TAG_STR2 = BYTES_LITERAL("\x0b")
TAG_STR3 = BYTES_LITERAL("\x0c")
TAG_STR4 = BYTES_LITERAL("\x0d")
TAG_STR_L1 = BYTES_LITERAL("\x0e")
TAG_STR_L4 = BYTES_LITERAL("\x0f")