def _stream_read(self, client): unpacker = msgpack.Unpacker() while not self._closing: try: client._read_until_future = client.stream.read_bytes(4096, partial=True) wire_bytes = yield client._read_until_future unpacker.feed(wire_bytes) for framed_msg in unpacker: body = framed_msg['body'] if body['enc'] != 'aes': # We only accept 'aes' encoded messages for 'id' continue crypticle = salt.crypt.Crypticle(self.opts, salt.master.SMaster.secrets['aes']['secret'].value) load = crypticle.loads(body['load']) if not self.aes_funcs.verify_minion(load['id'], load['tok']): continue client.id_ = load['id'] self._add_client_present(client) except tornado.iostream.StreamClosedError as e: log.debug('tcp stream to {0} closed, unable to recv'.format(client.address)) client.close() self._remove_client_present(client) self.clients.discard(client) break except Exception as e: log.error('Exception parsing response', exc_info=True) continue
def _stream_read(self, client): unpacker = salt.utils.msgpack.Unpacker() while not self._closing: try: client._read_until_future = client.stream.read_bytes( 4096, partial=True) wire_bytes = yield client._read_until_future unpacker.feed(wire_bytes) for framed_msg in unpacker: framed_msg = salt.transport.frame.decode_embedded_strs( framed_msg) body = framed_msg["body"] if self.presence_callback: self.presence_callback(client, body) except salt.ext.tornado.iostream.StreamClosedError as e: log.debug("tcp stream to %s closed, unable to recv", client.address) client.close() self.remove_presence_callback(client) self.clients.discard(client) break except Exception as e: # pylint: disable=broad-except log.error("Exception parsing response from %s", client.address, exc_info=True) continue
def publish_payload(self, package, topic_list=None): log.trace("TCP PubServer sending payload: %s \n\n %r", package, topic_list) payload = salt.transport.frame.frame_msg(package) to_remove = [] if topic_list: for topic in topic_list: sent = False for client in self.clients: if topic == client.id_: try: # Write the packed str yield client.stream.write(payload) sent = True # self.io_loop.add_future(f, lambda f: True) except salt.ext.tornado.iostream.StreamClosedError: to_remove.append(client) if not sent: log.debug("Publish target %s not connected %r", topic, self.clients) else: for client in self.clients: try: # Write the packed str yield client.stream.write(payload) except salt.ext.tornado.iostream.StreamClosedError: to_remove.append(client) for client in to_remove: log.debug("Subscriber at %s has disconnected from publisher", client.address) client.close() self._remove_client_present(client) self.clients.discard(client) log.trace("TCP PubServer finished publishing payload")
def shutdown(self): ''' Shutdown the whole server ''' for item in self.clients: client, address = item client.close() self.clients.remove(item)
def close(self): """ Close the server """ if self._closing: return self._closing = True for item in self.clients: client, address = item client.close() self.remove_client(item) try: self.stop() except OSError as exc: if exc.errno != 9: raise
def publish_payload(self, package): log.trace('TCP PubServer starting to publish payload') package = package[0] # ZMQ (The IPC calling us) ism :/ payload = frame_msg(salt.payload.unpackage(package)['payload'], raw_body=True) to_remove = [] for item in self.clients: client, address = item try: f = client.write(payload) self.io_loop.add_future(f, lambda f: True) except tornado.iostream.StreamClosedError: to_remove.append(item) for item in to_remove: client, address = item log.debug('Subscriber at {0} has disconnected from publisher'.format(address)) client.close() self.clients.remove(item) log.trace('TCP PubServer finished publishing payload')
def publish_payload(self, payload, _): payload = salt.transport.frame.frame_msg(payload['payload'], raw_body=True) log.debug('TCP PubServer sending payload: {0}'.format(payload)) to_remove = [] for item in self.clients: client, address = item try: # Write the packed str f = client.write(payload) self.io_loop.add_future(f, lambda f: True) except tornado.iostream.StreamClosedError: to_remove.append(item) for item in to_remove: client, address = item log.debug('Subscriber at {0} has disconnected from publisher'.format(address)) client.close() self.clients.remove(item) log.trace('TCP PubServer finished publishing payload')
def publish_payload(self, payload, _): log.debug('TCP PubServer sending payload: {0}'.format(payload)) payload = salt.transport.frame.frame_msg(payload['payload']) to_remove = [] for item in self.clients: client, address = item try: # Write the packed str f = client.write(payload) self.io_loop.add_future(f, lambda f: True) except tornado.iostream.StreamClosedError: to_remove.append(item) for item in to_remove: client, address = item log.debug('Subscriber at {0} has disconnected from publisher'.format(address)) client.close() self.clients.remove(item) log.trace('TCP PubServer finished publishing payload')
def publish_payload(self, package, _): log.debug('TCP PubServer sending payload: {0}'.format(package)) payload = salt.transport.frame.frame_msg(package['payload']) to_remove = [] if 'topic_lst' in package: topic_lst = package['topic_lst'] for topic in topic_lst: if topic in self.present: # This will rarely be a list of more than 1 item. It will # be more than 1 item if the minion disconnects from the # master in an unclean manner (eg cable yank), then # restarts and the master is yet to detect the disconnect # via TCP keep-alive. for client in self.present[topic]: try: # Write the packed str f = client.stream.write(payload) self.io_loop.add_future(f, lambda f: True) except tornado.iostream.StreamClosedError: to_remove.append(client) else: log.debug('Publish target {0} not connected'.format(topic)) else: for client in self.clients: try: # Write the packed str f = client.stream.write(payload) self.io_loop.add_future(f, lambda f: True) except tornado.iostream.StreamClosedError: to_remove.append(client) for client in to_remove: log.debug( 'Subscriber at {0} has disconnected from publisher'.format( client.address)) client.close() self._remove_client_present(client) self.clients.discard(client) log.trace('TCP PubServer finished publishing payload')
def test_message_client(self): """ test message client cleanup on close """ orig_loop = salt.ext.tornado.ioloop.IOLoop() orig_loop.make_current() opts = self.get_temp_config("master") client = SaltMessageClient(opts, self.listen_on, self.port) # Mock the io_loop's stop method so we know when it has been called. orig_loop.real_stop = orig_loop.stop orig_loop.stop_called = False def stop(*args, **kwargs): orig_loop.stop_called = True orig_loop.real_stop() orig_loop.stop = stop try: assert client.io_loop == orig_loop client.io_loop.run_sync(client.connect) # Ensure we are testing the _read_until_future and io_loop teardown assert client._stream is not None assert client._read_until_future is not None assert orig_loop.stop_called is True # The run_sync call will set stop_called, reset it orig_loop.stop_called = False client.close() # Stop should be called again, client's io_loop should be None assert orig_loop.stop_called is True assert client.io_loop is None finally: orig_loop.stop = orig_loop.real_stop del orig_loop.real_stop del orig_loop.stop_called
def publish_payload(self, package, _): log.debug('TCP PubServer sending payload: {0}'.format(package)) payload = salt.transport.frame.frame_msg(package['payload']) to_remove = [] if 'topic_lst' in package: topic_lst = package['topic_lst'] for topic in topic_lst: if topic in self.present: # This will rarely be a list of more than 1 item. It will # be more than 1 item if the minion disconnects from the # master in an unclean manner (eg cable yank), then # restarts and the master is yet to detect the disconnect # via TCP keep-alive. for client in self.present[topic]: try: # Write the packed str f = client.stream.write(payload) self.io_loop.add_future(f, lambda f: True) except tornado.iostream.StreamClosedError: to_remove.append(client) else: log.debug('Publish target {0} not connected'.format(topic)) else: for client in self.clients: try: # Write the packed str f = client.stream.write(payload) self.io_loop.add_future(f, lambda f: True) except tornado.iostream.StreamClosedError: to_remove.append(client) for client in to_remove: log.debug('Subscriber at {0} has disconnected from publisher'.format(client.address)) client.close() self._remove_client_present(client) self.clients.discard(client) log.trace('TCP PubServer finished publishing payload')