mirror of
https://github.com/All-Hands-AI/OpenHands.git
synced 2026-01-08 22:38:05 -05:00
feat(sandbox): add support for extra Docker build arguments (#5447)
This commit is contained in:
@@ -217,6 +217,9 @@ llm_config = 'gpt3'
|
|||||||
# Use host network
|
# Use host network
|
||||||
#use_host_network = false
|
#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 linting after editing
|
||||||
#enable_auto_lint = false
|
#enable_auto_lint = false
|
||||||
|
|
||||||
|
|||||||
@@ -48,6 +48,7 @@ class SandboxConfig:
|
|||||||
False # once enabled, OpenHands would lint files after editing
|
False # once enabled, OpenHands would lint files after editing
|
||||||
)
|
)
|
||||||
use_host_network: bool = False
|
use_host_network: bool = False
|
||||||
|
runtime_extra_build_args: list[str] | None = None
|
||||||
initialize_plugins: bool = True
|
initialize_plugins: bool = True
|
||||||
force_rebuild_runtime: bool = False
|
force_rebuild_runtime: bool = False
|
||||||
runtime_extra_deps: str | None = None
|
runtime_extra_deps: str | None = None
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ class RuntimeBuilder(abc.ABC):
|
|||||||
path: str,
|
path: str,
|
||||||
tags: list[str],
|
tags: list[str],
|
||||||
platform: str | None = None,
|
platform: str | None = None,
|
||||||
|
extra_build_args: list[str] | None = None,
|
||||||
) -> str:
|
) -> str:
|
||||||
"""Build the runtime image.
|
"""Build the runtime image.
|
||||||
|
|
||||||
@@ -15,6 +16,7 @@ class RuntimeBuilder(abc.ABC):
|
|||||||
path (str): The path to the runtime image's build directory.
|
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"]).
|
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.
|
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:
|
Returns:
|
||||||
str: The name:tag of the runtime image after build (e.g., "repo:sha").
|
str: The name:tag of the runtime image after build (e.g., "repo:sha").
|
||||||
|
|||||||
@@ -28,8 +28,8 @@ class DockerRuntimeBuilder(RuntimeBuilder):
|
|||||||
path: str,
|
path: str,
|
||||||
tags: list[str],
|
tags: list[str],
|
||||||
platform: str | None = None,
|
platform: str | None = None,
|
||||||
use_local_cache: bool = False,
|
|
||||||
extra_build_args: list[str] | None = None,
|
extra_build_args: list[str] | None = None,
|
||||||
|
use_local_cache: bool = False,
|
||||||
) -> str:
|
) -> str:
|
||||||
"""Builds a Docker image using BuildKit and handles the build logs appropriately.
|
"""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 = requests.Session()
|
||||||
self.session.headers.update({'X-API-Key': self.api_key})
|
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."""
|
"""Builds a Docker image using the Runtime API's /build endpoint."""
|
||||||
# Create a tar archive of the build context
|
# Create a tar archive of the build context
|
||||||
tar_buffer = io.BytesIO()
|
tar_buffer = io.BytesIO()
|
||||||
|
|||||||
@@ -229,6 +229,7 @@ class EventStreamRuntime(Runtime):
|
|||||||
platform=self.config.sandbox.platform,
|
platform=self.config.sandbox.platform,
|
||||||
extra_deps=self.config.sandbox.runtime_extra_deps,
|
extra_deps=self.config.sandbox.runtime_extra_deps,
|
||||||
force_rebuild=self.config.sandbox.force_rebuild_runtime,
|
force_rebuild=self.config.sandbox.force_rebuild_runtime,
|
||||||
|
extra_build_args=self.config.sandbox.runtime_extra_build_args,
|
||||||
)
|
)
|
||||||
|
|
||||||
self.log(
|
self.log(
|
||||||
|
|||||||
@@ -111,6 +111,7 @@ def build_runtime_image(
|
|||||||
build_folder: str | None = None,
|
build_folder: str | None = None,
|
||||||
dry_run: bool = False,
|
dry_run: bool = False,
|
||||||
force_rebuild: bool = False,
|
force_rebuild: bool = False,
|
||||||
|
extra_build_args: List[str] | None = None,
|
||||||
) -> str:
|
) -> str:
|
||||||
"""Prepares the final docker build folder.
|
"""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.
|
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
|
- 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
|
- 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
|
- 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:
|
Returns:
|
||||||
- str: <image_repo>:<MD5 hash>. Where MD5 hash is the hash of the docker build folder
|
- 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,
|
dry_run=dry_run,
|
||||||
force_rebuild=force_rebuild,
|
force_rebuild=force_rebuild,
|
||||||
platform=platform,
|
platform=platform,
|
||||||
|
extra_build_args=extra_build_args,
|
||||||
)
|
)
|
||||||
return result
|
return result
|
||||||
|
|
||||||
@@ -150,6 +153,7 @@ def build_runtime_image(
|
|||||||
dry_run=dry_run,
|
dry_run=dry_run,
|
||||||
force_rebuild=force_rebuild,
|
force_rebuild=force_rebuild,
|
||||||
platform=platform,
|
platform=platform,
|
||||||
|
extra_build_args=extra_build_args,
|
||||||
)
|
)
|
||||||
return result
|
return result
|
||||||
|
|
||||||
@@ -162,6 +166,7 @@ def build_runtime_image_in_folder(
|
|||||||
dry_run: bool,
|
dry_run: bool,
|
||||||
force_rebuild: bool,
|
force_rebuild: bool,
|
||||||
platform: str | None = None,
|
platform: str | None = None,
|
||||||
|
extra_build_args: List[str] | None = None,
|
||||||
) -> str:
|
) -> str:
|
||||||
runtime_image_repo, _ = get_runtime_image_repo_and_tag(base_image)
|
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)}'
|
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,
|
lock_tag,
|
||||||
versioned_tag,
|
versioned_tag,
|
||||||
platform,
|
platform,
|
||||||
|
extra_build_args=extra_build_args,
|
||||||
)
|
)
|
||||||
return hash_image_name
|
return hash_image_name
|
||||||
|
|
||||||
@@ -234,6 +240,7 @@ def build_runtime_image_in_folder(
|
|||||||
if build_from == BuildFromImageType.SCRATCH
|
if build_from == BuildFromImageType.SCRATCH
|
||||||
else None,
|
else None,
|
||||||
platform=platform,
|
platform=platform,
|
||||||
|
extra_build_args=extra_build_args,
|
||||||
)
|
)
|
||||||
|
|
||||||
return hash_image_name
|
return hash_image_name
|
||||||
@@ -339,6 +346,7 @@ def _build_sandbox_image(
|
|||||||
lock_tag: str,
|
lock_tag: str,
|
||||||
versioned_tag: str | None,
|
versioned_tag: str | None,
|
||||||
platform: str | None = 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"""
|
"""Build and tag the sandbox image. The image will be tagged with all tags that do not yet exist"""
|
||||||
names = [
|
names = [
|
||||||
@@ -350,7 +358,10 @@ def _build_sandbox_image(
|
|||||||
names = [name for name in names if not runtime_builder.image_exists(name, False)]
|
names = [name for name in names if not runtime_builder.image_exists(name, False)]
|
||||||
|
|
||||||
image_name = runtime_builder.build(
|
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:
|
if not image_name:
|
||||||
raise RuntimeError(f'Build failed for image {names}')
|
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',
|
f'{get_runtime_image_repo()}:{OH_VERSION}_mock-versioned-tag',
|
||||||
],
|
],
|
||||||
platform=None,
|
platform=None,
|
||||||
|
extra_build_args=None,
|
||||||
)
|
)
|
||||||
assert (
|
assert (
|
||||||
image_name
|
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
|
# VERSION tag will NOT be included except from scratch
|
||||||
],
|
],
|
||||||
platform=None,
|
platform=None,
|
||||||
|
extra_build_args=None,
|
||||||
)
|
)
|
||||||
mock_prep_build_folder.assert_called_once_with(
|
mock_prep_build_folder.assert_called_once_with(
|
||||||
ANY,
|
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
|
# VERSION tag will NOT be included except from scratch
|
||||||
],
|
],
|
||||||
platform=None,
|
platform=None,
|
||||||
|
extra_build_args=None,
|
||||||
)
|
)
|
||||||
mock_prep_build_folder.assert_called_once_with(
|
mock_prep_build_folder.assert_called_once_with(
|
||||||
ANY,
|
ANY,
|
||||||
|
|||||||
Reference in New Issue
Block a user