Skip to content

Commit

Permalink
Fix issue #6531: [Bug]: GITHUB_TOKEN would missing when the runtime r…
Browse files Browse the repository at this point in the history
…esume (#6533)
  • Loading branch information
openhands-agent authored Feb 4, 2025
1 parent 0d312a6 commit fe8b927
Show file tree
Hide file tree
Showing 3 changed files with 71 additions and 1 deletion.
14 changes: 13 additions & 1 deletion openhands/runtime/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -172,11 +172,14 @@ def add_env_vars(self, env_vars: dict[str, str]) -> None:
# 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()
Expand All @@ -190,6 +193,15 @@ def add_env_vars(self, env_vars: dict[str, str]) -> None:
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))
Expand Down
26 changes: 26 additions & 0 deletions openhands/runtime/impl/docker/docker_runtime.py
Original file line number Diff line number Diff line change
Expand Up @@ -401,6 +401,32 @@ def web_hosts(self):

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()
Expand Down
32 changes: 32 additions & 0 deletions tests/runtime/test_env_vars.py
Original file line number Diff line number Diff line change
Expand Up @@ -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)

0 comments on commit fe8b927

Please sign in to comment.