From 6ea51445815148b26b82d18004a3c4916896a772 Mon Sep 17 00:00:00 2001 From: enyst Date: Sun, 26 Oct 2025 20:20:54 +0000 Subject: [PATCH] runtime: allow overriding micromamba channel_alias via OH_CONDA_CHANNEL_ALIAS; keep -c conda-forge\n\n- Read OH_CONDA_CHANNEL_ALIAS and pass into Dockerfile template\n- Inject "micromamba config set channel_alias" when set (scratch build path)\n- Add unit tests to verify rendering with and without env var\n\nCo-authored-by: openhands --- openhands/runtime/utils/runtime_build.py | 2 + .../utils/runtime_templates/Dockerfile.j2 | 3 ++ .../runtime/builder/test_runtime_build.py | 38 +++++++++++++++++++ 3 files changed, 43 insertions(+) diff --git a/openhands/runtime/utils/runtime_build.py b/openhands/runtime/utils/runtime_build.py index 3b5281871a..4784f64fab 100644 --- a/openhands/runtime/utils/runtime_build.py +++ b/openhands/runtime/utils/runtime_build.py @@ -52,12 +52,14 @@ def _generate_dockerfile( ) template = env.get_template('Dockerfile.j2') + _channel_alias = os.getenv('OH_CONDA_CHANNEL_ALIAS') dockerfile_content = template.render( base_image=base_image, build_from_scratch=build_from == BuildFromImageType.SCRATCH, build_from_versioned=build_from == BuildFromImageType.VERSIONED, extra_deps=extra_deps if extra_deps is not None else '', enable_browser=enable_browser, + channel_alias=_channel_alias, ) return dockerfile_content diff --git a/openhands/runtime/utils/runtime_templates/Dockerfile.j2 b/openhands/runtime/utils/runtime_templates/Dockerfile.j2 index 51c0de535f..a3849733a8 100644 --- a/openhands/runtime/utils/runtime_templates/Dockerfile.j2 +++ b/openhands/runtime/utils/runtime_templates/Dockerfile.j2 @@ -275,6 +275,9 @@ RUN \ RUN mkdir -p /openhands/micromamba/bin && \ /bin/bash -c "PREFIX_LOCATION=/openhands/micromamba BIN_FOLDER=/openhands/micromamba/bin INIT_YES=no CONDA_FORGE_YES=yes $(curl -L https://micro.mamba.pm/install.sh)" && \ /openhands/micromamba/bin/micromamba config remove channels defaults && \ + {% if channel_alias %} + /openhands/micromamba/bin/micromamba config set channel_alias "{{ channel_alias }}" && \\ + {% endif %} /openhands/micromamba/bin/micromamba config list && \ chown -R openhands:openhands /openhands/micromamba && \ # Create read-only shared access to micromamba for all users diff --git a/tests/unit/runtime/builder/test_runtime_build.py b/tests/unit/runtime/builder/test_runtime_build.py index 306865c499..c95ed17361 100644 --- a/tests/unit/runtime/builder/test_runtime_build.py +++ b/tests/unit/runtime/builder/test_runtime_build.py @@ -218,6 +218,44 @@ def test_generate_dockerfile_build_from_versioned(): ) +def test_generate_dockerfile_channel_alias_included(monkeypatch): + # Use a direct import from the repository path to avoid importing a stale copy from /openhands/code + import importlib.util + from pathlib import Path + + base_dir = Path(__file__).resolve().parents[4] + mod_path = base_dir / 'openhands' / 'runtime' / 'utils' / 'runtime_build.py' + spec = importlib.util.spec_from_file_location('runtime_build_local', str(mod_path)) + rb = importlib.util.module_from_spec(spec) + assert spec and spec.loader + spec.loader.exec_module(rb) + + base_image = 'debian:11' + alias = 'https://repo.prefix.dev' + monkeypatch.setenv('OH_CONDA_CHANNEL_ALIAS', alias) + dockerfile_content = rb._generate_dockerfile( + base_image, + build_from=rb.BuildFromImageType.SCRATCH, + ) + assert f'micromamba config set channel_alias "{alias}"' in dockerfile_content + assert '-c conda-forge' in dockerfile_content + + +def test_generate_dockerfile_channel_alias_unset(): + base_image = 'debian:11' + prev = os.environ.get('OH_CONDA_CHANNEL_ALIAS') + os.environ.pop('OH_CONDA_CHANNEL_ALIAS', None) + try: + dockerfile_content = _generate_dockerfile( + base_image, + build_from=BuildFromImageType.SCRATCH, + ) + finally: + if prev is not None: + os.environ['OH_CONDA_CHANNEL_ALIAS'] = prev + assert 'micromamba config set channel_alias' not in dockerfile_content + + def test_get_runtime_image_repo_and_tag_eventstream(): base_image = 'debian:11' img_repo, img_tag = get_runtime_image_repo_and_tag(base_image)