|
|
@@ -1,4 +1,5 @@
|
|
|
import atexit
|
|
|
+import json
|
|
|
import os
|
|
|
import sys
|
|
|
import tarfile
|
|
|
@@ -78,7 +79,9 @@ class DockerSSHBox(Sandbox):
|
|
|
)
|
|
|
raise ex
|
|
|
|
|
|
- self.instance_id = sid + str(uuid.uuid4()) if sid is not None else str(uuid.uuid4())
|
|
|
+ self.instance_id = (
|
|
|
+ sid + str(uuid.uuid4()) if sid is not None else str(uuid.uuid4())
|
|
|
+ )
|
|
|
|
|
|
# TODO: this timeout is actually essential - need a better way to set it
|
|
|
# if it is too short, the container may still waiting for previous
|
|
|
@@ -100,6 +103,12 @@ class DockerSSHBox(Sandbox):
|
|
|
self.setup_user()
|
|
|
self.start_ssh_session()
|
|
|
atexit.register(self.close)
|
|
|
+ super().__init__()
|
|
|
+
|
|
|
+ def add_to_env(self, key: str, value: str):
|
|
|
+ super().add_to_env(key, value)
|
|
|
+ # Note: json.dumps gives us nice escaping for free
|
|
|
+ self.execute(f'export {key}={json.dumps(value)}')
|
|
|
|
|
|
def setup_user(self):
|
|
|
# Make users sudoers passwordless
|
|
|
@@ -107,6 +116,7 @@ class DockerSSHBox(Sandbox):
|
|
|
exit_code, logs = self.container.exec_run(
|
|
|
['/bin/bash', '-c', r"echo '%sudo ALL=(ALL) NOPASSWD:ALL' >> /etc/sudoers"],
|
|
|
workdir=SANDBOX_WORKSPACE_DIR,
|
|
|
+ environment=self._env,
|
|
|
)
|
|
|
if exit_code != 0:
|
|
|
raise Exception(
|
|
|
@@ -117,12 +127,14 @@ class DockerSSHBox(Sandbox):
|
|
|
exit_code, logs = self.container.exec_run(
|
|
|
['/bin/bash', '-c', 'id -u opendevin'],
|
|
|
workdir=SANDBOX_WORKSPACE_DIR,
|
|
|
+ environment=self._env,
|
|
|
)
|
|
|
if exit_code == 0:
|
|
|
# User exists, delete it
|
|
|
exit_code, logs = self.container.exec_run(
|
|
|
['/bin/bash', '-c', 'userdel -r opendevin'],
|
|
|
workdir=SANDBOX_WORKSPACE_DIR,
|
|
|
+ environment=self._env,
|
|
|
)
|
|
|
if exit_code != 0:
|
|
|
raise Exception(f'Failed to remove opendevin user in sandbox: {logs}')
|
|
|
@@ -136,6 +148,7 @@ class DockerSSHBox(Sandbox):
|
|
|
f'useradd -rm -d /home/opendevin -s /bin/bash -g root -G sudo -u {USER_ID} opendevin',
|
|
|
],
|
|
|
workdir=SANDBOX_WORKSPACE_DIR,
|
|
|
+ environment=self._env,
|
|
|
)
|
|
|
if exit_code != 0:
|
|
|
raise Exception(f'Failed to create opendevin user in sandbox: {logs}')
|
|
|
@@ -146,6 +159,7 @@ class DockerSSHBox(Sandbox):
|
|
|
f"echo 'opendevin:{self._ssh_password}' | chpasswd",
|
|
|
],
|
|
|
workdir=SANDBOX_WORKSPACE_DIR,
|
|
|
+ environment=self._env,
|
|
|
)
|
|
|
if exit_code != 0:
|
|
|
raise Exception(f'Failed to set password in sandbox: {logs}')
|
|
|
@@ -154,6 +168,7 @@ class DockerSSHBox(Sandbox):
|
|
|
exit_code, logs = self.container.exec_run(
|
|
|
['/bin/bash', '-c', 'chown opendevin:root /home/opendevin'],
|
|
|
workdir=SANDBOX_WORKSPACE_DIR,
|
|
|
+ environment=self._env,
|
|
|
)
|
|
|
if exit_code != 0:
|
|
|
raise Exception(
|
|
|
@@ -162,6 +177,7 @@ class DockerSSHBox(Sandbox):
|
|
|
exit_code, logs = self.container.exec_run(
|
|
|
['/bin/bash', '-c', f'chown opendevin:root {SANDBOX_WORKSPACE_DIR}'],
|
|
|
workdir=SANDBOX_WORKSPACE_DIR,
|
|
|
+ environment=self._env,
|
|
|
)
|
|
|
if exit_code != 0:
|
|
|
# This is not a fatal error, just a warning
|
|
|
@@ -173,12 +189,14 @@ class DockerSSHBox(Sandbox):
|
|
|
# change password for root
|
|
|
['/bin/bash', '-c', f"echo 'root:{self._ssh_password}' | chpasswd"],
|
|
|
workdir=SANDBOX_WORKSPACE_DIR,
|
|
|
+ environment=self._env,
|
|
|
)
|
|
|
if exit_code != 0:
|
|
|
raise Exception(f'Failed to set password for root in sandbox: {logs}')
|
|
|
exit_code, logs = self.container.exec_run(
|
|
|
['/bin/bash', '-c', "echo 'opendevin-sandbox' > /etc/hostname"],
|
|
|
workdir=SANDBOX_WORKSPACE_DIR,
|
|
|
+ environment=self._env,
|
|
|
)
|
|
|
|
|
|
def start_ssh_session(self):
|
|
|
@@ -266,6 +284,7 @@ class DockerSSHBox(Sandbox):
|
|
|
exit_code, logs = self.container.exec_run(
|
|
|
['/bin/bash', '-c', f'mkdir -p {sandbox_dest}'],
|
|
|
workdir=SANDBOX_WORKSPACE_DIR,
|
|
|
+ environment=self._env,
|
|
|
)
|
|
|
if exit_code != 0:
|
|
|
raise Exception(
|
|
|
@@ -301,7 +320,10 @@ class DockerSSHBox(Sandbox):
|
|
|
|
|
|
def execute_in_background(self, cmd: str) -> Process:
|
|
|
result = self.container.exec_run(
|
|
|
- self.get_exec_cmd(cmd), socket=True, workdir=SANDBOX_WORKSPACE_DIR
|
|
|
+ self.get_exec_cmd(cmd),
|
|
|
+ socket=True,
|
|
|
+ workdir=SANDBOX_WORKSPACE_DIR,
|
|
|
+ environment=self._env,
|
|
|
)
|
|
|
result.output._sock.setblocking(0)
|
|
|
pid = self.get_pid(cmd)
|
|
|
@@ -311,7 +333,7 @@ class DockerSSHBox(Sandbox):
|
|
|
return bg_cmd
|
|
|
|
|
|
def get_pid(self, cmd):
|
|
|
- exec_result = self.container.exec_run('ps aux')
|
|
|
+ exec_result = self.container.exec_run('ps aux', environment=self._env)
|
|
|
processes = exec_result.output.decode('utf-8').splitlines()
|
|
|
cmd = ' '.join(self.get_exec_cmd(cmd))
|
|
|
|
|
|
@@ -327,7 +349,9 @@ class DockerSSHBox(Sandbox):
|
|
|
bg_cmd = self.background_commands[id]
|
|
|
if bg_cmd.pid is not None:
|
|
|
self.container.exec_run(
|
|
|
- f'kill -9 {bg_cmd.pid}', workdir=SANDBOX_WORKSPACE_DIR
|
|
|
+ f'kill -9 {bg_cmd.pid}',
|
|
|
+ workdir=SANDBOX_WORKSPACE_DIR,
|
|
|
+ environment=self._env,
|
|
|
)
|
|
|
assert isinstance(bg_cmd, DockerProcess)
|
|
|
bg_cmd.result.output.close()
|