Ejemplo n.º 1
0
 def run(self):
     chan = self._channel
     q = self._q
     try:
         poller = poll()
         poller.register(chan)
         while True:
             # select on a paramiko ssh channel object does not ever return it in the writable list, so channels don't exactly emulate the socket api
             fd_events = poller.poll(TICK)
             # will wakeup evey TICK seconds to check if something to send, more if something to read (due to select returning chan in readable list)
             if fd_events != []:
                 data = chan.recv(BUF_SIZE)
                 #print('chan.recv(%r) = %r' % (BUF_SIZE, data))
                 if data:
                     self._buffer.write(data)
                     self._parse()
                 else:
                     raise SessionCloseError(self._buffer.getvalue())
             if not q.empty() and chan.send_ready():
                 logger.debug("Sending message")
                 data = compat.force_text(q.get()) + MSG_DELIM
                 while data:
                     n = chan.send(data)
                     if n <= 0:
                         raise SessionCloseError(self._buffer.getvalue(),
                                                 data)
                     data = data[n:]
     except Exception as e:
         logger.debug("Broke out of main loop, error=%r", e)
         self._dispatch_error(e)
         self.close()
Ejemplo n.º 2
0
    def run(self):
        chan = self._channel
        q = self._q

        def start_delim(data_len):
            return '\n#%s\n' % (data_len)

        try:
            s = selectors.DefaultSelector()
            s.register(chan, selectors.EVENT_READ)
            self.logger.debug('selector type = %s', s.__class__.__name__)
            while True:

                # Will wakeup evey TICK seconds to check if something
                # to send, more quickly if something to read (due to
                # select returning chan in readable list).
                events = s.select(timeout=TICK)
                if events:
                    data = chan.recv(BUF_SIZE)
                    if data:
                        try:
                            self.parser.parse(data)
                        except SAXFilterXMLNotFoundError:
                            self.logger.debug(
                                'switching from sax to dom parsing')
                            self.parser = DefaultXMLParser(self)
                            self.parser.parse(data)
                    elif self._closing.is_set():
                        # End of session, expected
                        break
                    else:
                        # End of session, unexpected
                        raise SessionCloseError(self._buffer.getvalue())
                if not q.empty() and chan.send_ready():
                    self.logger.debug("Sending message")
                    data = q.get()
                    if self._base == NetconfBase.BASE_11:
                        data = "%s%s%s" % (start_delim(
                            len(data)), data, END_DELIM)
                    else:
                        data = "%s%s" % (data, MSG_DELIM)
                    self.logger.info("Sending:\n%s", data)
                    while data:
                        n = chan.send(data)
                        if n <= 0:
                            raise SessionCloseError(self._buffer.getvalue(),
                                                    data)
                        data = data[n:]
        except Exception as e:
            self.logger.debug("Broke out of main loop, error=%r", e)
            self._dispatch_error(e)
            self.close()
Ejemplo n.º 3
0
 def run(self):
     chan = self._channel
     q = self._q
     try:
         while True:
             r, w, e = select([chan.stdout], [], [], TICK)
             data = []
             if r:
                 while True:
                     data.append(chan.stdout.readline())
                     if MSG_DELIM in data[-1]:
                         break
                 if data:
                     self._buffer.write(b''.join(data))
                     self._parse()
                 else:
                     raise SessionCloseError(self._buffer.getvalue())
             if not q.empty():
                 data = q.get() + MSG_DELIM
                 while data:
                     chan.stdin.write(data)
                     chan.stdin.flush()
                     data = False
     except Exception as e:
         self.close()
         self._dispatch_error(e)
Ejemplo n.º 4
0
    def run(self):
        chan = self._channel
        q = self._q

        def start_delim(data_len):
            return '\n#%s\n' % (data_len)

        try:
            while True:
                # select on a paramiko ssh channel object does not ever return it in the writable list, so channels don't exactly emulate the socket api
                r, w, e = select([chan], [], [], TICK)
                # will wakeup evey TICK seconds to check if something to send, more if something to read (due to select returning chan in readable list)
                if r:
                    data = chan.recv(BUF_SIZE)
                    if data:
                        self._buffer.write(data)
                        if self._server_capabilities:
                            if 'urn:ietf:params:netconf:base:1.1' in self._server_capabilities and 'urn:ietf:params:netconf:base:1.1' in self._client_capabilities:
                                logger.debug(
                                    "Selecting netconf:base:1.1 for encoding")
                                self._parse11()
                            elif 'urn:ietf:params:netconf:base:1.0' in self._server_capabilities or 'urn:ietf:params:xml:ns:netconf:base:1.0' in self._server_capabilities or 'urn:ietf:params:netconf:base:1.0' in self._client_capabilities:
                                logger.debug(
                                    "Selecting netconf:base:1.0 for encoding")
                                self._parse10()
                            else:
                                raise Exception
                        else:
                            self._parse10()  # HELLO msg uses EOM markers.
                    else:
                        raise SessionCloseError(self._buffer.getvalue())
                if not q.empty() and chan.send_ready():
                    logger.debug("Sending message")
                    data = q.get()
                    try:
                        # send a HELLO msg using v1.0 EOM markers.
                        validated_element(
                            data,
                            tags=
                            '{urn:ietf:params:xml:ns:netconf:base:1.0}hello')
                        data = "%s%s" % (data, MSG_DELIM)
                    except XMLError:
                        # this is not a HELLO msg
                        # we publish v1.1 support
                        if 'urn:ietf:params:netconf:base:1.1' in self._client_capabilities:
                            if self._server_capabilities:
                                if 'urn:ietf:params:netconf:base:1.1' in self._server_capabilities:
                                    # send using v1.1 chunked framing
                                    data = "%s%s%s" % (start_delim(
                                        len(data)), data, END_DELIM)
                                elif 'urn:ietf:params:netconf:base:1.0' in self._server_capabilities or 'urn:ietf:params:xml:ns:netconf:base:1.0' in self._server_capabilities:
                                    # send using v1.0 EOM markers
                                    data = "%s%s" % (data, MSG_DELIM)
                                else:
                                    raise Exception
                            else:
                                logger.debug(
                                    'HELLO msg was sent, but server capabilities are still not known'
                                )
                                raise Exception
                        # we publish only v1.0 support
                        else:
                            # send using v1.0 EOM markers
                            data = "%s%s" % (data, MSG_DELIM)
                    finally:
                        logger.debug("Sending: %s", data)
                        while data:
                            n = chan.send(data)
                            if n <= 0:
                                raise SessionCloseError(
                                    self._buffer.getvalue(), data)
                            data = data[n:]
        except Exception as e:
            logger.debug("Broke out of main loop, error=%r", e)
            self._dispatch_error(e)
            self.close()