Fix issue #6531: [Bug]: GITHUB_TOKEN would missing when the runtime resume (#6533)

This commit is contained in:
OpenHands 2025-02-04 17:48:25 -05:00 committed by GitHub
parent 0d312a645a
commit fe8b92743b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 71 additions and 1 deletions

View File

@ -172,11 +172,14 @@ class Runtime(FileEditRuntimeMixin):
# Note: we don't log the vars values, they're leaking info
logger.debug('Added env vars to IPython')
# Add env vars to the Bash shell
# Add env vars to the Bash shell and .bashrc for persistence
cmd = ''
bashrc_cmd = ''
for key, value in env_vars.items():
# Note: json.dumps gives us nice escaping for free
cmd += f'export {key}={json.dumps(value)}; '
# Add to .bashrc if not already present
bashrc_cmd += f'grep -q "^export {key}=" ~/.bashrc || echo "export {key}={json.dumps(value)}" >> ~/.bashrc; '
if not cmd:
return
cmd = cmd.strip()
@ -190,6 +193,15 @@ class Runtime(FileEditRuntimeMixin):
f'Failed to add env vars [{env_vars.keys()}] to environment: {obs.content}'
)
# Add to .bashrc for persistence
bashrc_cmd = bashrc_cmd.strip()
logger.debug(f'Adding env var to .bashrc: {env_vars.keys()}')
obs = self.run(CmdRunAction(bashrc_cmd))
if not isinstance(obs, CmdOutputObservation) or obs.exit_code != 0:
raise RuntimeError(
f'Failed to add env vars [{env_vars.keys()}] to .bashrc: {obs.content}'
)
def on_event(self, event: Event) -> None:
if isinstance(event, Action):
asyncio.get_event_loop().run_until_complete(self._handle_action(event))

View File

@ -401,6 +401,32 @@ class DockerRuntime(ActionExecutionClient):
return hosts
def pause(self):
"""Pause the runtime by stopping the container.
This is different from container.stop() as it ensures environment variables are properly preserved."""
if not self.container:
raise RuntimeError("Container not initialized")
# First, ensure all environment variables are properly persisted in .bashrc
# This is already handled by add_env_vars in base.py
# Stop the container
self.container.stop()
self.log('debug', f'Container {self.container_name} paused')
def resume(self):
"""Resume the runtime by starting the container.
This is different from container.start() as it ensures environment variables are properly restored."""
if not self.container:
raise RuntimeError("Container not initialized")
# Start the container
self.container.start()
self.log('debug', f'Container {self.container_name} resumed')
# Wait for the container to be ready
self._wait_until_alive()
@classmethod
async def delete(cls, conversation_id: str):
docker_client = cls._init_docker_client()

View File

@ -81,3 +81,35 @@ def test_env_vars_added_by_config(temp_dir, runtime_cls):
and obs.content.strip().split('\r\n')[0].strip() == 'added_value'
)
_close_test_runtime(runtime)
def test_docker_runtime_env_vars_persist_after_restart(temp_dir):
from openhands.runtime.impl.docker.docker_runtime import DockerRuntime
runtime = _load_runtime(temp_dir, DockerRuntime)
# Add a test environment variable
runtime.add_env_vars({'GITHUB_TOKEN': 'test_token'})
# Verify the variable is set in current session
obs = runtime.run_action(CmdRunAction(command='echo $GITHUB_TOKEN'))
assert obs.exit_code == 0
assert obs.content.strip().split('\r\n')[0].strip() == 'test_token'
# Verify the variable is added to .bashrc
obs = runtime.run_action(
CmdRunAction(command='grep "^export GITHUB_TOKEN=" ~/.bashrc')
)
assert obs.exit_code == 0
assert 'export GITHUB_TOKEN=' in obs.content
# Test pause/resume cycle
runtime.pause()
runtime.resume()
# Verify the variable persists after restart
obs = runtime.run_action(CmdRunAction(command='echo $GITHUB_TOKEN'))
assert obs.exit_code == 0
assert obs.content.strip().split('\r\n')[0].strip() == 'test_token'
_close_test_runtime(runtime)