mirror of
https://github.com/OpenHands/OpenHands.git
synced 2025-12-26 05:48:36 +08:00
feat(sandbox): add support for extra Docker build arguments (#5447)
This commit is contained in:
parent
ffd472d6b8
commit
7e4c1c733b
@ -217,6 +217,9 @@ llm_config = 'gpt3'
|
||||
# Use host network
|
||||
#use_host_network = false
|
||||
|
||||
# runtime extra build args
|
||||
#runtime_extra_build_args = ["--network=host", "--add-host=host.docker.internal:host-gateway"]
|
||||
|
||||
# Enable auto linting after editing
|
||||
#enable_auto_lint = false
|
||||
|
||||
|
||||
@ -48,6 +48,7 @@ class SandboxConfig:
|
||||
False # once enabled, OpenHands would lint files after editing
|
||||
)
|
||||
use_host_network: bool = False
|
||||
runtime_extra_build_args: list[str] | None = None
|
||||
initialize_plugins: bool = True
|
||||
force_rebuild_runtime: bool = False
|
||||
runtime_extra_deps: str | None = None
|
||||
|
||||
@ -8,6 +8,7 @@ class RuntimeBuilder(abc.ABC):
|
||||
path: str,
|
||||
tags: list[str],
|
||||
platform: str | None = None,
|
||||
extra_build_args: list[str] | None = None,
|
||||
) -> str:
|
||||
"""Build the runtime image.
|
||||
|
||||
@ -15,6 +16,7 @@ class RuntimeBuilder(abc.ABC):
|
||||
path (str): The path to the runtime image's build directory.
|
||||
tags (list[str]): The tags to apply to the runtime image (e.g., ["repo:my-repo", "sha:my-sha"]).
|
||||
platform (str, optional): The target platform for the build. Defaults to None.
|
||||
extra_build_args (list[str], optional): Additional build arguments to pass to the builder. Defaults to None.
|
||||
|
||||
Returns:
|
||||
str: The name:tag of the runtime image after build (e.g., "repo:sha").
|
||||
|
||||
@ -28,8 +28,8 @@ class DockerRuntimeBuilder(RuntimeBuilder):
|
||||
path: str,
|
||||
tags: list[str],
|
||||
platform: str | None = None,
|
||||
use_local_cache: bool = False,
|
||||
extra_build_args: list[str] | None = None,
|
||||
use_local_cache: bool = False,
|
||||
) -> str:
|
||||
"""Builds a Docker image using BuildKit and handles the build logs appropriately.
|
||||
|
||||
|
||||
@ -23,7 +23,13 @@ class RemoteRuntimeBuilder(RuntimeBuilder):
|
||||
self.session = requests.Session()
|
||||
self.session.headers.update({'X-API-Key': self.api_key})
|
||||
|
||||
def build(self, path: str, tags: list[str], platform: str | None = None) -> str:
|
||||
def build(
|
||||
self,
|
||||
path: str,
|
||||
tags: list[str],
|
||||
platform: str | None = None,
|
||||
extra_build_args: list[str] | None = None,
|
||||
) -> str:
|
||||
"""Builds a Docker image using the Runtime API's /build endpoint."""
|
||||
# Create a tar archive of the build context
|
||||
tar_buffer = io.BytesIO()
|
||||
|
||||
@ -229,6 +229,7 @@ class EventStreamRuntime(Runtime):
|
||||
platform=self.config.sandbox.platform,
|
||||
extra_deps=self.config.sandbox.runtime_extra_deps,
|
||||
force_rebuild=self.config.sandbox.force_rebuild_runtime,
|
||||
extra_build_args=self.config.sandbox.runtime_extra_build_args,
|
||||
)
|
||||
|
||||
self.log(
|
||||
|
||||
@ -111,6 +111,7 @@ def build_runtime_image(
|
||||
build_folder: str | None = None,
|
||||
dry_run: bool = False,
|
||||
force_rebuild: bool = False,
|
||||
extra_build_args: List[str] | None = None,
|
||||
) -> str:
|
||||
"""Prepares the final docker build folder.
|
||||
If dry_run is False, it will also build the OpenHands runtime Docker image using the docker build folder.
|
||||
@ -123,6 +124,7 @@ def build_runtime_image(
|
||||
- build_folder (str): The directory to use for the build. If not provided a temporary directory will be used
|
||||
- dry_run (bool): if True, it will only ready the build folder. It will not actually build the Docker image
|
||||
- force_rebuild (bool): if True, it will create the Dockerfile which uses the base_image
|
||||
- extra_build_args (List[str]): Additional build arguments to pass to the builder
|
||||
|
||||
Returns:
|
||||
- str: <image_repo>:<MD5 hash>. Where MD5 hash is the hash of the docker build folder
|
||||
@ -139,6 +141,7 @@ def build_runtime_image(
|
||||
dry_run=dry_run,
|
||||
force_rebuild=force_rebuild,
|
||||
platform=platform,
|
||||
extra_build_args=extra_build_args,
|
||||
)
|
||||
return result
|
||||
|
||||
@ -150,6 +153,7 @@ def build_runtime_image(
|
||||
dry_run=dry_run,
|
||||
force_rebuild=force_rebuild,
|
||||
platform=platform,
|
||||
extra_build_args=extra_build_args,
|
||||
)
|
||||
return result
|
||||
|
||||
@ -162,6 +166,7 @@ def build_runtime_image_in_folder(
|
||||
dry_run: bool,
|
||||
force_rebuild: bool,
|
||||
platform: str | None = None,
|
||||
extra_build_args: List[str] | None = None,
|
||||
) -> str:
|
||||
runtime_image_repo, _ = get_runtime_image_repo_and_tag(base_image)
|
||||
lock_tag = f'oh_v{oh_version}_{get_hash_for_lock_files(base_image)}'
|
||||
@ -193,6 +198,7 @@ def build_runtime_image_in_folder(
|
||||
lock_tag,
|
||||
versioned_tag,
|
||||
platform,
|
||||
extra_build_args=extra_build_args,
|
||||
)
|
||||
return hash_image_name
|
||||
|
||||
@ -234,6 +240,7 @@ def build_runtime_image_in_folder(
|
||||
if build_from == BuildFromImageType.SCRATCH
|
||||
else None,
|
||||
platform=platform,
|
||||
extra_build_args=extra_build_args,
|
||||
)
|
||||
|
||||
return hash_image_name
|
||||
@ -339,6 +346,7 @@ def _build_sandbox_image(
|
||||
lock_tag: str,
|
||||
versioned_tag: str | None,
|
||||
platform: str | None = None,
|
||||
extra_build_args: List[str] | None = None,
|
||||
):
|
||||
"""Build and tag the sandbox image. The image will be tagged with all tags that do not yet exist"""
|
||||
names = [
|
||||
@ -350,7 +358,10 @@ def _build_sandbox_image(
|
||||
names = [name for name in names if not runtime_builder.image_exists(name, False)]
|
||||
|
||||
image_name = runtime_builder.build(
|
||||
path=str(build_folder), tags=names, platform=platform
|
||||
path=str(build_folder),
|
||||
tags=names,
|
||||
platform=platform,
|
||||
extra_build_args=extra_build_args,
|
||||
)
|
||||
if not image_name:
|
||||
raise RuntimeError(f'Build failed for image {names}')
|
||||
|
||||
@ -239,6 +239,7 @@ def test_build_runtime_image_from_scratch():
|
||||
f'{get_runtime_image_repo()}:{OH_VERSION}_mock-versioned-tag',
|
||||
],
|
||||
platform=None,
|
||||
extra_build_args=None,
|
||||
)
|
||||
assert (
|
||||
image_name
|
||||
@ -333,6 +334,7 @@ def test_build_runtime_image_exact_hash_not_exist_and_lock_exist():
|
||||
# VERSION tag will NOT be included except from scratch
|
||||
],
|
||||
platform=None,
|
||||
extra_build_args=None,
|
||||
)
|
||||
mock_prep_build_folder.assert_called_once_with(
|
||||
ANY,
|
||||
@ -391,6 +393,7 @@ def test_build_runtime_image_exact_hash_not_exist_and_lock_not_exist_and_version
|
||||
# VERSION tag will NOT be included except from scratch
|
||||
],
|
||||
platform=None,
|
||||
extra_build_args=None,
|
||||
)
|
||||
mock_prep_build_folder.assert_called_once_with(
|
||||
ANY,
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user