From 2ef518f06384e1805a245c9173054abd16081035 Mon Sep 17 00:00:00 2001 From: Cansu <31902747+ckavili@users.noreply.github.com> Date: Thu, 24 Jul 2025 00:12:36 +0200 Subject: [PATCH] feat: Add configurable runtime support for issue resolver and fix: Kubernetes pod naming limits (#9877) --- openhands/core/setup.py | 22 ++++++++++++++++++++-- openhands/resolver/issue_resolver.py | 5 ++++- openhands/resolver/resolve_issue.py | 6 ++++++ 3 files changed, 30 insertions(+), 3 deletions(-) diff --git a/openhands/core/setup.py b/openhands/core/setup.py index 2ef674b122..3a210b768a 100644 --- a/openhands/core/setup.py +++ b/openhands/core/setup.py @@ -225,9 +225,27 @@ def create_controller( def generate_sid(config: OpenHandsConfig, session_name: str | None = None) -> str: - """Generate a session id based on the session name and the jwt secret.""" + """Generate a session id based on the session name and the jwt secret. + + The session ID is kept short to ensure Kubernetes resource names don't exceed + the 63-character limit when prefixed with 'openhands-runtime-' (18 chars). + Total length is limited to 32 characters to allow for suffixes like '-svc', '-pvc'. + """ session_name = session_name or str(uuid.uuid4()) jwt_secret = config.jwt_secret hash_str = hashlib.sha256(f'{session_name}{jwt_secret}'.encode('utf-8')).hexdigest() - return f'{session_name}-{hash_str[:16]}' + + # Limit total session ID length to 32 characters for Kubernetes compatibility: + # - 'openhands-runtime-' (18 chars) + session_id (32 chars) = 50 chars + # - Leaves 13 chars for suffixes like '-svc' (4), '-pvc' (4), '-ingress-code' (13) + if len(session_name) > 16: + # If session_name is too long, use first 16 chars + 15-char hash for better readability + # e.g., "vscode-extension" -> "vscode-extensio-{15-char-hash}" + session_id = f'{session_name[:16]}-{hash_str[:15]}' + else: + # If session_name is short enough, use it + remaining space for hash + remaining_chars = 32 - len(session_name) - 1 # -1 for the dash + session_id = f'{session_name}-{hash_str[:remaining_chars]}' + + return session_id[:32] # Ensure we never exceed 32 characters diff --git a/openhands/resolver/issue_resolver.py b/openhands/resolver/issue_resolver.py index 89f26129d2..1c93ea0ffd 100644 --- a/openhands/resolver/issue_resolver.py +++ b/openhands/resolver/issue_resolver.py @@ -149,6 +149,7 @@ class IssueResolver: args.base_container_image, args.runtime_container_image, args.is_experimental, + args.runtime, ) self.owner = owner @@ -182,9 +183,11 @@ class IssueResolver: base_container_image: str | None, runtime_container_image: str | None, is_experimental: bool, + runtime: str | None = None, ) -> OpenHandsConfig: config.default_agent = 'CodeActAgent' - config.runtime = 'docker' + # Use provided runtime or fallback to config value or default to 'docker' + config.runtime = runtime or config.runtime or 'docker' config.max_budget_per_task = 4 config.max_iterations = max_iterations diff --git a/openhands/resolver/resolve_issue.py b/openhands/resolver/resolve_issue.py index f9d3cf8ae9..bd050386e5 100644 --- a/openhands/resolver/resolve_issue.py +++ b/openhands/resolver/resolve_issue.py @@ -45,6 +45,12 @@ def main() -> None: default=None, help='Container image to use.', ) + parser.add_argument( + '--runtime', + type=str, + default=None, + help='Runtime environment to use (default: docker).', + ) parser.add_argument( '--max-iterations', type=int,