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()
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()
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)
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()