__init__.py 1.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051
  1. import os
  2. import subprocess
  3. import time
  4. import uuid
  5. from dataclasses import dataclass
  6. from openhands.core.logger import openhands_logger as logger
  7. from openhands.runtime.plugins.requirement import Plugin, PluginRequirement
  8. from openhands.runtime.utils.system import check_port_available
  9. from openhands.utils.shutdown_listener import should_continue
  10. @dataclass
  11. class VSCodeRequirement(PluginRequirement):
  12. name: str = 'vscode'
  13. class VSCodePlugin(Plugin):
  14. name: str = 'vscode'
  15. async def initialize(self, username: str):
  16. self.vscode_port = int(os.environ['VSCODE_PORT'])
  17. self.vscode_connection_token = str(uuid.uuid4())
  18. assert check_port_available(self.vscode_port)
  19. cmd = (
  20. f"su - {username} -s /bin/bash << 'EOF'\n"
  21. f'sudo chown -R {username}:{username} /openhands/.openvscode-server\n'
  22. 'cd /workspace\n'
  23. f'exec /openhands/.openvscode-server/bin/openvscode-server --host 0.0.0.0 --connection-token {self.vscode_connection_token} --port {self.vscode_port}\n'
  24. 'EOF'
  25. )
  26. print(cmd)
  27. self.gateway_process = subprocess.Popen(
  28. cmd,
  29. stderr=subprocess.STDOUT,
  30. shell=True,
  31. )
  32. # read stdout until the kernel gateway is ready
  33. output = ''
  34. while should_continue() and self.gateway_process.stdout is not None:
  35. line = self.gateway_process.stdout.readline().decode('utf-8')
  36. print(line)
  37. output += line
  38. if 'at' in line:
  39. break
  40. time.sleep(1)
  41. logger.debug('Waiting for VSCode server to start...')
  42. logger.debug(
  43. f'VSCode server started at port {self.vscode_port}. Output: {output}'
  44. )