def test_encode_decode(): total_messages = 10 encoder = recordio.Encoder(lambda s: json.dumps(s).encode("UTF-8")) decoder = recordio.Decoder(lambda s: json.loads(s.decode("UTF-8"))) message = {"type": "ATTACH_CONTAINER_OUTPUT", "containerId": "123456789"} encoded = b"" for i in range(total_messages): encoded += encoder.encode(message) all_records = [] offset = 0 chunk_size = 5 while offset < len(encoded): records = decoder.decode(encoded[offset:offset + chunk_size]) print(records) all_records.extend(records) offset += chunk_size print(encoded) print(all_records) assert len(all_records) == total_messages for record in all_records: assert record == message
def test_encode(): encoder = recordio.Encoder(lambda s: json.dumps(s).encode("UTF-8")) message = {"type": "ATTACH_CONTAINER_OUTPUT", "containerId": "123456789"} encoded = encoder.encode(message) string = json.dumps(message) assert encoded == (str(len(string)) + "\n" + string).encode("UTF-8")
def test_encode_decode(): total_messages = 10 try: encoder = recordio.Encoder(lambda s: bytes(json.dumps(s), "UTF-8")) except Exception as exception: raise DCOSException("Error instantiating 'RecordIO' encoder: {error}" .format(error=exception)) try: decoder = recordio.Decoder(lambda s: json.loads(s.decode("UTF-8"))) except Exception as exception: raise DCOSException("Error instantiating 'RecordIO' decoder: {error}" .format(error=exception)) try: message = { "type": "ATTACH_CONTAINER_OUTPUT", "containerId": "123456789" } encoded = b"" for i in range(total_messages): encoded += encoder.encode(message) except Exception as exception: raise DCOSException("Error encoding 'RecordIO' message: {error}" .format(error=exception)) try: all_records = [] offset = 0 chunk_size = 5 while offset < len(encoded): records = decoder.decode(encoded[offset:offset + chunk_size]) all_records.extend(records) offset += chunk_size assert len(all_records) == total_messages for record in all_records: assert record == message except Exception as exception: raise DCOSException("Error decoding 'RecordIO' messages: {error}" .format(error=exception))
def test_encode(): try: encoder = recordio.Encoder(lambda s: bytes(json.dumps(s), "UTF-8")) except Exception as exception: raise DCOSException("Error instantiating 'RecordIO' encoder: {error}" .format(error=exception)) try: message = { "type": "ATTACH_CONTAINER_OUTPUT", "containerId": "123456789" } encoded = encoder.encode(message) except Exception as exception: raise DCOSException("Error encoding 'RecordIO' message: {error}" .format(error=exception)) string = json.dumps(message) assert encoded == bytes(str(len(string)) + "\n" + string, "UTF-8")
def __init__(self, task_id, cmd=None, args=None, interactive=False, tty=False): # Store relevant parameters of the call for later. self.cmd = cmd self.interactive = interactive self.tty = tty self.args = args # Create a client and grab a reference to the DC/OS master. client = DCOSClient() master = get_master(client) # Get the task and make sure its container was launched by the UCR. # Since task's containers are launched by the UCR by default, we want # to allow most tasks to pass through unchecked. The only exception is # when a task has an explicit container specified and it is not of type # "MESOS". Having a type of "MESOS" implies that it was launched by the # UCR -- all other types imply it was not. task_obj = master.task(task_id) if "container" in task_obj.dict(): if "type" in task_obj.dict()["container"]: if task_obj.dict()["container"]["type"] != "MESOS": raise DCOSException( "This command is only supported for tasks" " launched by the Universal Container Runtime (UCR).") # Get the URL to the agent running the task. if client._mesos_master_url: self.agent_url = client.slave_url( slave_id="", private_url=task_obj.slave().http_url(), path="api/v1") else: self.agent_url = client.slave_url(slave_id=task_obj.slave()['id'], private_url="", path="api/v1") # Grab a reference to the container ID for the task. self.parent_id = master.get_container_id(task_id) # Generate a new UUID for the nested container # used to run commands passed to `task exec`. self.container_id = str(uuid.uuid4()) # Set up a recordio encoder and decoder # for any incoming and outgoing messages. self.encoder = recordio.Encoder( lambda s: bytes(json.dumps(s, ensure_ascii=False), "UTF-8")) self.decoder = recordio.Decoder( lambda s: json.loads(s.decode("UTF-8"))) # Set up queues to send messages between threads used for # reading/writing to STDIN/STDOUT/STDERR and threads # sending/receiving data over the network. self.input_queue = Queue() self.output_queue = Queue() # Set up an event to block attaching # input until attaching output is complete. self.attach_input_event = threading.Event() self.attach_input_event.clear() # Set up an event to block printing the output # until an attach input event has successfully # been established. self.print_output_event = threading.Event() self.print_output_event.clear() # Set up an event to block the main thread # from exiting until signaled to do so. self.exit_event = threading.Event() self.exit_event.clear() # Use a class variable to store exceptions thrown on # other threads and raise them on the main thread before # exiting. self.exception = None
def __init__(self, task_id, cmd=None, args=None, interactive=False, tty=False): # Store relevant parameters of the call for later. self.cmd = cmd self.interactive = interactive self.tty = tty self.args = args # Create a client and grab a reference to the DC/OS master. client = DCOSClient() master = get_master(client) # Get the URL to the agent running the task. task_obj = master.task(task_id) if client._mesos_master_url: self.agent_url = client.slave_url( slave_id="", private_url=task_obj.slave().http_url(), path="api/v1") else: self.agent_url = client.slave_url(slave_id=task_obj.slave()['id'], private_url="", path="api/v1") # Grab a reference to the container ID for the task. self.parent_id = master.get_container_id(task_id) # Generate a new UUID for the nested container # used to run commands passed to `task exec`. self.container_id = str(uuid.uuid4()) # Set up a recordio encoder and decoder # for any incoming and outgoing messages. self.encoder = recordio.Encoder( lambda s: bytes(json.dumps(s, ensure_ascii=False), "UTF-8")) self.decoder = recordio.Decoder( lambda s: json.loads(s.decode("UTF-8"))) # Set up queues to send messages between threads used for # reading/writing to STDIN/STDOUT/STDERR and threads # sending/receiving data over the network. self.input_queue = Queue() self.output_queue = Queue() # Set up an event to block attaching # input until attaching output is complete. self.attach_input_event = threading.Event() self.attach_input_event.clear() # Set up an event to block printing the output # until an attach input event has successfully # been established. self.print_output_event = threading.Event() self.print_output_event.clear() # Set up an event to block the main thread # from exiting until signaled to do so. self.exit_event = threading.Event() self.exit_event.clear() # Use a class variable to store exceptions thrown on # other threads and raise them on the main thread before # exiting. self.exception = None
import socket import socketserver import subprocess import time import threading from dcos import recordio from functools import partial from http.server import HTTPServer, BaseHTTPRequestHandler PORT = 8888 containers = {} tasksToContainer = {"1": "a", "2": "b"} encoder = recordio.Encoder( lambda s: bytes(json.dumps(s, ensure_ascii=False), "UTF-8")) decoder = recordio.Decoder(lambda s: json.loads(s.decode("UTF-8"))) ROUTES = [('/mesos/master/api/v1')] class StreamingTCPServer(socketserver.ThreadingMixIn, socketserver.TCPServer): def server_bind(self): self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) self.socket.bind(self.server_address) class StreamingRequestHandler(BaseHTTPRequestHandler, object): def __init__(self, request, client_address, server): super(StreamingRequestHandler, self).__init__(request, client_address, server)