|
|
@@ -6,13 +6,55 @@ from typing import Tuple
|
|
|
|
|
|
|
|
|
class BackgroundCommand:
|
|
|
+ """
|
|
|
+ Represents a background command execution
|
|
|
+ """
|
|
|
+
|
|
|
def __init__(self, id: int, command: str, result, pid: int):
|
|
|
+ """
|
|
|
+ Initialize a BackgroundCommand instance.
|
|
|
+
|
|
|
+ Args:
|
|
|
+ id (int): The identifier of the command.
|
|
|
+ command (str): The command to be executed.
|
|
|
+ result: The result of the command execution.
|
|
|
+ pid (int): The process ID (PID) of the command.
|
|
|
+ """
|
|
|
self.id = id
|
|
|
self.command = command
|
|
|
self.result = result
|
|
|
self.pid = pid
|
|
|
|
|
|
def parse_docker_exec_output(self, logs: bytes) -> Tuple[bytes, bytes]:
|
|
|
+ """
|
|
|
+ When you execute a command using `exec` in a docker container, the output produced will be in bytes. this function parses the output of a Docker exec command.
|
|
|
+
|
|
|
+ Example:
|
|
|
+ Considering you have a docker container named `my_container` up and running
|
|
|
+ $ docker exec my_container echo "Hello OpenDevin!"
|
|
|
+ >> b'\x00\x00\x00\x00\x00\x00\x00\x13Hello OpenDevin!'
|
|
|
+
|
|
|
+ Such binary logs will be processed by this function.
|
|
|
+
|
|
|
+ The function handles message types, padding, and byte order to create a usable result. The primary goal is to convert raw container logs into a more structured format for further analysis or display.
|
|
|
+
|
|
|
+ The function also returns a tail of bytes to ensure that no information is lost. It is a way to handle edge cases and maintain data integrity.
|
|
|
+
|
|
|
+ >> output_bytes = b'\x00\x00\x00\x00\x00\x00\x00\x13Hello OpenDevin!'
|
|
|
+ >> parsed_output, remaining_bytes = parse_docker_exec_output(output_bytes)
|
|
|
+
|
|
|
+ >> print(parsed_output)
|
|
|
+ b'Hello OpenDevin!'
|
|
|
+
|
|
|
+ >> print(remaining_bytes)
|
|
|
+ b''
|
|
|
+
|
|
|
+ Args:
|
|
|
+ logs (bytes): The raw output logs of the command.
|
|
|
+
|
|
|
+ Returns:
|
|
|
+ Tuple[bytes, bytes]: A tuple containing the parsed output and any remaining data.
|
|
|
+ """
|
|
|
res = b''
|
|
|
tail = b''
|
|
|
i = 0
|
|
|
@@ -40,6 +82,30 @@ class BackgroundCommand:
|
|
|
return res, tail
|
|
|
|
|
|
def read_logs(self) -> str:
|
|
|
+ """
|
|
|
+ Read and decode the logs of the command.
|
|
|
+
|
|
|
+ This function continuously reads the standard output of a subprocess and
|
|
|
+ processes the output using the parse_docker_exec_output function to handle
|
|
|
+ binary log messages. It concatenates and decodes the output bytes into a
|
|
|
+ string, ensuring that no partial messages are lost during reading.
|
|
|
+
|
|
|
+ Dummy Example:
|
|
|
+
|
|
|
+ >> cmd = 'echo "Hello OpenDevin!"'
|
|
|
+ >> result = subprocess.Popen(
|
|
|
+ cmd, shell=True, stdout=subprocess.PIPE,
|
|
|
+ stderr=subprocess.STDOUT, text=True, cwd='.'
|
|
|
+ )
|
|
|
+ >> bg_cmd = BackgroundCommand(id, cmd = cmd, result = result, pid)
|
|
|
+
|
|
|
+ >> logs = bg_cmd.read_logs()
|
|
|
+ >> print(logs)
|
|
|
+ Hello OpenDevin!
|
|
|
+
|
|
|
+ Returns:
|
|
|
+ str: The decoded logs(string) of the command.
|
|
|
+ """
|
|
|
# TODO: get an exit code if process is exited
|
|
|
logs = b''
|
|
|
last_remains = b''
|