mirror of
				https://github.com/All-Hands-AI/OpenHands.git
				synced 2024-08-29 01:18:33 +03:00 
			
		
		
		
	fix: pip not available in runtime (#3306)
* try to fix pip unavailable
* update test case for pip
* force rebuild in CI
* remove extra symlink
* fix newline
* added semi-colon to line 31
* Dockerfile.j2: activate env at the end
* Revert "Dockerfile.j2: activate env at the end"
This reverts commit cf2f565102.
* cleanup Dockerfile
* switch default python image
* remove image agnostic (no longer used)
* fix tests
* switch to nikolaik/python-nodejs:python3.11-nodejs22
* fix test
* fix test
* revert docker
* update template
---------
Co-authored-by: tobitege <tobitege@gmx.de>
Co-authored-by: Graham Neubig <neubig@gmail.com>
			
			
This commit is contained in:
		
							
								
								
									
										4
									
								
								.github/workflows/ghcr.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										4
									
								
								.github/workflows/ghcr.yml
									
									
									
									
										vendored
									
									
								
							| @@ -81,7 +81,7 @@ jobs: | ||||
|     strategy: | ||||
|       matrix: | ||||
|         image: ['od_runtime'] | ||||
|         base_image: ['ubuntu:22.04'] | ||||
|         base_image: ['nikolaik/python-nodejs:python3.11-nodejs22'] | ||||
|         platform: ['amd64', 'arm64'] | ||||
|     steps: | ||||
|       - name: Checkout | ||||
| @@ -115,7 +115,7 @@ jobs: | ||||
|       - name: Install Python dependencies using Poetry | ||||
|         run: make install-python-dependencies | ||||
|       - name: Create source distribution and Dockerfile | ||||
|         run: poetry run python3 opendevin/runtime/utils/runtime_build.py --base_image ${{ matrix.base_image }} --build_folder containers/runtime | ||||
|         run: poetry run python3 opendevin/runtime/utils/runtime_build.py --base_image ${{ matrix.base_image }} --build_folder containers/runtime --force_rebuild | ||||
|       - name: Build and export image | ||||
|         id: build | ||||
|         run: | | ||||
|   | ||||
| @@ -174,7 +174,7 @@ llm_config = 'gpt3' | ||||
| #user_id = 1000 | ||||
|  | ||||
| # Container image to use for the sandbox | ||||
| #container_image = "ghcr.io/opendevin/sandbox:main" | ||||
| #container_image = "nikolaik/python-nodejs:python3.11-nodejs22" | ||||
|  | ||||
| # Use host network | ||||
| #use_host_network = false | ||||
|   | ||||
| @@ -62,7 +62,7 @@ def get_config( | ||||
|         runtime='eventstream', | ||||
|         max_iterations=metadata.max_iterations, | ||||
|         sandbox=SandboxConfig( | ||||
|             container_image='ubuntu:22.04', | ||||
|             container_image='python:3.11-bookworm', | ||||
|             enable_auto_lint=False, | ||||
|             use_host_network=False, | ||||
|         ), | ||||
|   | ||||
| @@ -44,7 +44,7 @@ def get_config( | ||||
|         runtime='eventstream', | ||||
|         max_iterations=metadata.max_iterations, | ||||
|         sandbox=SandboxConfig( | ||||
|             container_image='ubuntu:22.04', | ||||
|             container_image='python:3.11-bookworm', | ||||
|             enable_auto_lint=True, | ||||
|             use_host_network=False, | ||||
|         ), | ||||
|   | ||||
| @@ -75,7 +75,7 @@ def get_config( | ||||
|         runtime='eventstream', | ||||
|         max_iterations=metadata.max_iterations, | ||||
|         sandbox=SandboxConfig( | ||||
|             container_image='ubuntu:22.04', | ||||
|             container_image='python:3.11-bookworm', | ||||
|             enable_auto_lint=True, | ||||
|             use_host_network=False, | ||||
|         ), | ||||
|   | ||||
| @@ -40,7 +40,7 @@ def get_config( | ||||
|         runtime='eventstream', | ||||
|         max_iterations=metadata.max_iterations, | ||||
|         sandbox=SandboxConfig( | ||||
|             container_image='ubuntu:22.04', | ||||
|             container_image='python:3.11-bookworm', | ||||
|             enable_auto_lint=False, | ||||
|             use_host_network=False, | ||||
|         ), | ||||
|   | ||||
| @@ -51,7 +51,7 @@ def get_config( | ||||
|         runtime='eventstream', | ||||
|         max_iterations=metadata.max_iterations, | ||||
|         sandbox=SandboxConfig( | ||||
|             container_image='ubuntu:22.04', | ||||
|             container_image='python:3.11-bookworm', | ||||
|             enable_auto_lint=True, | ||||
|             use_host_network=False, | ||||
|         ), | ||||
|   | ||||
| @@ -42,7 +42,7 @@ def get_config( | ||||
|         runtime='eventstream', | ||||
|         max_iterations=metadata.max_iterations, | ||||
|         sandbox=SandboxConfig( | ||||
|             container_image='ubuntu:22.04', | ||||
|             container_image='python:3.11-bookworm', | ||||
|             enable_auto_lint=True, | ||||
|             use_host_network=False, | ||||
|         ), | ||||
|   | ||||
| @@ -65,7 +65,7 @@ def get_config( | ||||
|         runtime='eventstream', | ||||
|         max_iterations=metadata.max_iterations, | ||||
|         sandbox=SandboxConfig( | ||||
|             container_image='ubuntu:22.04', | ||||
|             container_image='python:3.11-bookworm', | ||||
|             enable_auto_lint=True, | ||||
|             use_host_network=False, | ||||
|         ), | ||||
|   | ||||
| @@ -86,7 +86,7 @@ def get_config( | ||||
|         runtime='eventstream', | ||||
|         max_iterations=metadata.max_iterations, | ||||
|         sandbox=SandboxConfig( | ||||
|             container_image='ubuntu:22.04', | ||||
|             container_image='python:3.11-bookworm', | ||||
|             enable_auto_lint=True, | ||||
|             use_host_network=False, | ||||
|         ), | ||||
|   | ||||
| @@ -45,7 +45,7 @@ def get_config( | ||||
|         runtime='eventstream', | ||||
|         max_iterations=metadata.max_iterations, | ||||
|         sandbox=SandboxConfig( | ||||
|             container_image='ubuntu:22.04', | ||||
|             container_image='python:3.11-bookworm', | ||||
|             enable_auto_lint=True, | ||||
|             use_host_network=False, | ||||
|         ), | ||||
|   | ||||
| @@ -54,7 +54,7 @@ def get_config( | ||||
|         runtime='eventstream', | ||||
|         max_iterations=metadata.max_iterations, | ||||
|         sandbox=SandboxConfig( | ||||
|             container_image='ubuntu:22.04', | ||||
|             container_image='python:3.11-bookworm', | ||||
|             enable_auto_lint=True, | ||||
|             use_host_network=False, | ||||
|             browsergym_eval_env=env_id, | ||||
|   | ||||
| @@ -166,9 +166,7 @@ class SandboxConfig(metaclass=Singleton): | ||||
|     """ | ||||
|  | ||||
|     api_hostname: str = 'localhost' | ||||
|     container_image: str = ( | ||||
|         'ubuntu:22.04'  # default to ubuntu:22.04 for eventstream runtime | ||||
|     ) | ||||
|     container_image: str = 'nikolaik/python-nodejs:python3.11-nodejs22'  # default to nikolaik/python-nodejs:python3.11-nodejs22 for eventstream runtime | ||||
|     user_id: int = os.getuid() if hasattr(os, 'getuid') else 1000 | ||||
|     timeout: int = 120 | ||||
|     enable_auto_lint: bool = ( | ||||
|   | ||||
| @@ -1,113 +0,0 @@ | ||||
| """This module contains functions for building and managing the agnostic sandbox image. | ||||
|  | ||||
| This WILL BE DEPRECATED when EventStreamRuntime is fully implemented and adopted. | ||||
| """ | ||||
|  | ||||
| import tempfile | ||||
|  | ||||
| import docker | ||||
|  | ||||
| from opendevin.core.logger import opendevin_logger as logger | ||||
|  | ||||
|  | ||||
| def generate_dockerfile(base_image: str) -> str: | ||||
|     """Generate the Dockerfile content for the agnostic sandbox image based on user-provided base image. | ||||
|  | ||||
|     NOTE: This is only tested on debian yet. | ||||
|     """ | ||||
|     # FIXME: Remove the requirement of ssh in future version | ||||
|     dockerfile_content = ( | ||||
|         f'FROM {base_image}\n' | ||||
|         'RUN apt update && apt install -y openssh-server wget sudo\n' | ||||
|         'RUN mkdir -p -m0755 /var/run/sshd\n' | ||||
|         'RUN mkdir -p /opendevin && mkdir -p /opendevin/logs && chmod 777 /opendevin/logs\n' | ||||
|         'RUN echo "" > /opendevin/bash.bashrc\n' | ||||
|         'RUN if [ ! -d /opendevin/miniforge3 ]; then \\\n' | ||||
|         '        wget --progress=bar:force -O Miniforge3.sh "https://github.com/conda-forge/miniforge/releases/latest/download/Miniforge3-$(uname)-$(uname -m).sh" && \\\n' | ||||
|         '        bash Miniforge3.sh -b -p /opendevin/miniforge3 && \\\n' | ||||
|         '        rm Miniforge3.sh && \\\n' | ||||
|         '        chmod -R g+w /opendevin/miniforge3 && \\\n' | ||||
|         '        bash -c ". /opendevin/miniforge3/etc/profile.d/conda.sh && conda config --set changeps1 False && conda config --append channels conda-forge"; \\\n' | ||||
|         '    fi\n' | ||||
|         'RUN /opendevin/miniforge3/bin/pip install --upgrade pip\n' | ||||
|         'RUN /opendevin/miniforge3/bin/pip install jupyterlab notebook jupyter_kernel_gateway flake8\n' | ||||
|         'RUN /opendevin/miniforge3/bin/pip install python-docx PyPDF2 python-pptx pylatexenc openai\n' | ||||
|     ).strip() | ||||
|     return dockerfile_content | ||||
|  | ||||
|  | ||||
| def _build_sandbox_image( | ||||
|     base_image: str, target_image_name: str, docker_client: docker.DockerClient | ||||
| ): | ||||
|     try: | ||||
|         with tempfile.TemporaryDirectory() as temp_dir: | ||||
|             dockerfile_content = generate_dockerfile(base_image) | ||||
|  | ||||
|             logger.info(f'Building agnostic sandbox image: {target_image_name}') | ||||
|             logger.info( | ||||
|                 ( | ||||
|                     f'===== Dockerfile content =====\n' | ||||
|                     f'{dockerfile_content}\n' | ||||
|                     f'===============================' | ||||
|                 ) | ||||
|             ) | ||||
|             with open(f'{temp_dir}/Dockerfile', 'w') as file: | ||||
|                 file.write(dockerfile_content) | ||||
|  | ||||
|             api_client = docker_client.api | ||||
|             build_logs = api_client.build( | ||||
|                 path=temp_dir, tag=target_image_name, rm=True, decode=True | ||||
|             ) | ||||
|  | ||||
|             for log in build_logs: | ||||
|                 if 'stream' in log: | ||||
|                     print(log['stream'].strip()) | ||||
|                 elif 'error' in log: | ||||
|                     logger.error(log['error'].strip()) | ||||
|                 else: | ||||
|                     logger.info(str(log)) | ||||
|  | ||||
|         logger.info(f'Image {target_image_name} built successfully') | ||||
|     except docker.errors.BuildError as e: | ||||
|         logger.error(f'Sandbox image build failed: {e}') | ||||
|         raise e | ||||
|     except Exception as e: | ||||
|         logger.error(f'An error occurred during sandbox image build: {e}') | ||||
|         raise e | ||||
|  | ||||
|  | ||||
| def _get_new_image_name(base_image: str) -> str: | ||||
|     prefix = 'od_sandbox' | ||||
|     if ':' not in base_image: | ||||
|         base_image = base_image + ':latest' | ||||
|  | ||||
|     [repo, tag] = base_image.split(':') | ||||
|     repo = repo.replace('/', '___') | ||||
|     return f'{prefix}:{repo}__{tag}' | ||||
|  | ||||
|  | ||||
| def get_od_sandbox_image(base_image: str, docker_client: docker.DockerClient) -> str: | ||||
|     """Return the sandbox image name based on user-provided base image. | ||||
|  | ||||
|     The returned sandbox image is assumed to contains all the required dependencies for OpenDevin. | ||||
|     If the sandbox image is not found, it will be built. | ||||
|     """ | ||||
|     # OpenDevin's offcial sandbox already contains the required dependencies for OpenDevin. | ||||
|     if 'ghcr.io/opendevin/sandbox' in base_image: | ||||
|         return base_image | ||||
|  | ||||
|     new_image_name = _get_new_image_name(base_image) | ||||
|  | ||||
|     # Detect if the sandbox image is built | ||||
|     images = docker_client.images.list() | ||||
|     for image in images: | ||||
|         if new_image_name in image.tags: | ||||
|             logger.info('Found existing od_sandbox image, reuse:' + new_image_name) | ||||
|             return new_image_name | ||||
|  | ||||
|     # If the sandbox image is not found, build it | ||||
|     logger.info( | ||||
|         f'od_sandbox image is not found for {base_image}, will build: {new_image_name}' | ||||
|     ) | ||||
|     _build_sandbox_image(base_image, new_image_name, docker_client) | ||||
|     return new_image_name | ||||
| @@ -239,6 +239,7 @@ def build_runtime_image( | ||||
|     extra_deps: str | None = None, | ||||
|     docker_build_folder: str | None = None, | ||||
|     dry_run: bool = False, | ||||
|     force_rebuild: bool = False, | ||||
| ) -> str: | ||||
|     """Build the runtime image for the OpenDevin runtime. | ||||
|  | ||||
| @@ -277,7 +278,10 @@ def build_runtime_image( | ||||
|     # 2. If the exact hash is not found, we will FIRST try to re-build it | ||||
|     # by leveraging the non-hash `generic_runtime_image_name` to save some time | ||||
|     # from re-building the dependencies (e.g., poetry install, apt install) | ||||
|     elif _check_image_exists(generic_runtime_image_name, docker_client): | ||||
|     elif ( | ||||
|         _check_image_exists(generic_runtime_image_name, docker_client) | ||||
|         and not force_rebuild | ||||
|     ): | ||||
|         logger.info( | ||||
|             f'Cannot find matched hash for image [{hash_runtime_image_name}]\n' | ||||
|             f'Will try to re-build it from latest [{generic_runtime_image_name}] image to potentially save ' | ||||
| @@ -319,6 +323,10 @@ def build_runtime_image( | ||||
|     # 3. If the image is not found AND we cannot re-use the non-hash latest relavant image, | ||||
|     # we will build it completely from scratch | ||||
|     else: | ||||
|         if force_rebuild: | ||||
|             logger.info( | ||||
|                 f'Force re-build: Will try to re-build image [{generic_runtime_image_name}] from scratch.\n' | ||||
|             ) | ||||
|         cur_docker_build_folder = docker_build_folder or tempfile.mkdtemp() | ||||
|         _new_from_scratch_hash = prep_docker_build_folder( | ||||
|             cur_docker_build_folder, | ||||
| @@ -352,8 +360,11 @@ def build_runtime_image( | ||||
|  | ||||
| if __name__ == '__main__': | ||||
|     parser = argparse.ArgumentParser() | ||||
|     parser.add_argument('--base_image', type=str, default='ubuntu:22.04') | ||||
|     parser.add_argument( | ||||
|         '--base_image', type=str, default='nikolaik/python-nodejs:python3.11-nodejs22' | ||||
|     ) | ||||
|     parser.add_argument('--build_folder', type=str, default=None) | ||||
|     parser.add_argument('--force_rebuild', action='store_true', default=False) | ||||
|     args = parser.parse_args() | ||||
|  | ||||
|     if args.build_folder is not None: | ||||
| @@ -373,6 +384,7 @@ if __name__ == '__main__': | ||||
|                 docker_client=docker.from_env(), | ||||
|                 docker_build_folder=temp_dir, | ||||
|                 dry_run=True, | ||||
|                 force_rebuild=args.force_rebuild, | ||||
|             ) | ||||
|             _runtime_image_repo, runtime_image_hash_tag = runtime_image_hash_name.split( | ||||
|                 ':' | ||||
|   | ||||
| @@ -18,13 +18,6 @@ RUN apt-get update && \ | ||||
|     apt-get clean && \ | ||||
|     rm -rf /var/lib/apt/lists/* | ||||
|  | ||||
| # Install Python if not already installed | ||||
| RUN if [ ! -e /usr/bin/python ]; then \ | ||||
|     apt-get update && \ | ||||
|     apt-get install -y python3 && \ | ||||
|     ln -s /usr/bin/python3 /usr/bin/python; \ | ||||
| fi | ||||
|  | ||||
| # Create necessary directories | ||||
| RUN mkdir -p /opendevin && \ | ||||
|     mkdir -p /opendevin/logs && \ | ||||
|   | ||||
| @@ -59,7 +59,7 @@ mkdir -p $WORKSPACE_BASE | ||||
| TEST_RUNTIME="${TEST_RUNTIME:-eventstream}"  # can be server or eventstream | ||||
| # TODO: set this as default after ServerRuntime is deprecated | ||||
| if [ "$TEST_RUNTIME" == "eventstream" ] && [ -z "$SANDBOX_CONTAINER_IMAGE" ]; then | ||||
|   SANDBOX_CONTAINER_IMAGE="ubuntu:22.04" | ||||
|   SANDBOX_CONTAINER_IMAGE="nikolaik/python-nodejs:python3.11-nodejs22" | ||||
| fi | ||||
|  | ||||
| MAX_ITERATIONS=15 | ||||
|   | ||||
| @@ -358,7 +358,7 @@ def test_defaults_dict_after_updates(default_config): | ||||
|     assert defaults_after_updates['sandbox']['timeout']['default'] == 120 | ||||
|     assert ( | ||||
|         defaults_after_updates['sandbox']['container_image']['default'] | ||||
|         == 'ubuntu:22.04' | ||||
|         == 'nikolaik/python-nodejs:python3.11-nodejs22' | ||||
|     ) | ||||
|     assert defaults_after_updates == initial_defaults | ||||
|  | ||||
|   | ||||
| @@ -1,51 +0,0 @@ | ||||
| from unittest.mock import MagicMock, patch | ||||
|  | ||||
| from opendevin.runtime.utils.image_agnostic import ( | ||||
|     _get_new_image_name, | ||||
|     generate_dockerfile, | ||||
|     get_od_sandbox_image, | ||||
| ) | ||||
|  | ||||
|  | ||||
| def test_generate_dockerfile(): | ||||
|     base_image = 'debian:11' | ||||
|     dockerfile_content = generate_dockerfile(base_image) | ||||
|     assert base_image in dockerfile_content | ||||
|     assert ( | ||||
|         'RUN apt update && apt install -y openssh-server wget sudo' | ||||
|         in dockerfile_content | ||||
|     ) | ||||
|  | ||||
|  | ||||
| def test_get_new_image_name_legacy(): | ||||
|     # test non-eventstream runtime (sandbox-based) | ||||
|     base_image = 'debian:11' | ||||
|     new_image_name = _get_new_image_name(base_image) | ||||
|     assert new_image_name == 'od_sandbox:debian__11' | ||||
|  | ||||
|     base_image = 'ubuntu:22.04' | ||||
|     new_image_name = _get_new_image_name(base_image) | ||||
|     assert new_image_name == 'od_sandbox:ubuntu__22.04' | ||||
|  | ||||
|     base_image = 'ubuntu' | ||||
|     new_image_name = _get_new_image_name(base_image) | ||||
|     assert new_image_name == 'od_sandbox:ubuntu__latest' | ||||
|  | ||||
|  | ||||
| @patch('opendevin.runtime.utils.image_agnostic._build_sandbox_image') | ||||
| @patch('opendevin.runtime.utils.image_agnostic.docker.DockerClient') | ||||
| def test_get_od_sandbox_image(mock_docker_client, mock_build_sandbox_image): | ||||
|     base_image = 'debian:11' | ||||
|     mock_docker_client.images.list.return_value = [ | ||||
|         MagicMock(tags=['od_sandbox:debian__11']) | ||||
|     ] | ||||
|  | ||||
|     image_name = get_od_sandbox_image(base_image, mock_docker_client) | ||||
|     assert image_name == 'od_sandbox:debian__11' | ||||
|  | ||||
|     mock_docker_client.images.list.return_value = [] | ||||
|     image_name = get_od_sandbox_image(base_image, mock_docker_client) | ||||
|     assert image_name == 'od_sandbox:debian__11' | ||||
|     mock_build_sandbox_image.assert_called_once_with( | ||||
|         base_image, 'od_sandbox:debian__11', mock_docker_client | ||||
|     ) | ||||
| @@ -83,7 +83,9 @@ def enable_auto_lint(request): | ||||
|     return request.param | ||||
|  | ||||
|  | ||||
| @pytest.fixture(scope='module', params=['ubuntu:22.04', 'debian:11']) | ||||
| @pytest.fixture( | ||||
|     scope='module', params=['nikolaik/python-nodejs:python3.11-nodejs22', 'debian:11'] | ||||
| ) | ||||
| def container_image(request): | ||||
|     time.sleep(1) | ||||
|     return request.param | ||||
| @@ -127,7 +129,7 @@ async def _load_runtime( | ||||
|         if 'od_runtime' not in cur_container_image and cur_container_image not in { | ||||
|             'xingyaoww/od-eval-miniwob:v1.0' | ||||
|         }:  # a special exception list | ||||
|             cur_container_image = 'ubuntu:22.04' | ||||
|             cur_container_image = 'nikolaik/python-nodejs:python3.11-nodejs22' | ||||
|             logger.warning( | ||||
|                 f'`{config.sandbox.container_image}` is not an od_runtime image. Will use `{cur_container_image}` as the container image for testing.' | ||||
|             ) | ||||
| @@ -1033,6 +1035,13 @@ async def test_bash_python_version(temp_dir, box_class): | ||||
|     assert obs.exit_code == 0 | ||||
|     # Should not error out | ||||
|  | ||||
|     action = CmdRunAction(command='pip --version') | ||||
|     logger.info(action, extra={'msg_type': 'ACTION'}) | ||||
|     obs = await runtime.run_action(action) | ||||
|     logger.info(obs, extra={'msg_type': 'OBSERVATION'}) | ||||
|     assert obs.exit_code == 0 | ||||
|     # Should not error out | ||||
|  | ||||
|     await runtime.close() | ||||
|     await asyncio.sleep(1) | ||||
|  | ||||
|   | ||||
| @@ -62,7 +62,7 @@ def test_put_source_code_to_dir(temp_dir): | ||||
| def test_docker_build_folder(temp_dir): | ||||
|     prep_docker_build_folder( | ||||
|         temp_dir, | ||||
|         base_image='ubuntu:22.04', | ||||
|         base_image='nikolaik/python-nodejs:python3.11-nodejs22', | ||||
|         skip_init=False, | ||||
|     ) | ||||
|  | ||||
| @@ -81,14 +81,14 @@ def test_docker_build_folder(temp_dir): | ||||
| def test_hash_folder_same(temp_dir): | ||||
|     dir_hash_1 = prep_docker_build_folder( | ||||
|         temp_dir, | ||||
|         base_image='ubuntu:22.04', | ||||
|         base_image='nikolaik/python-nodejs:python3.11-nodejs22', | ||||
|         skip_init=False, | ||||
|     ) | ||||
|  | ||||
|     with tempfile.TemporaryDirectory() as temp_dir_2: | ||||
|         dir_hash_2 = prep_docker_build_folder( | ||||
|             temp_dir_2, | ||||
|             base_image='ubuntu:22.04', | ||||
|             base_image='nikolaik/python-nodejs:python3.11-nodejs22', | ||||
|             skip_init=False, | ||||
|         ) | ||||
|     assert dir_hash_1 == dir_hash_2 | ||||
| @@ -97,14 +97,14 @@ def test_hash_folder_same(temp_dir): | ||||
| def test_hash_folder_diff_init(temp_dir): | ||||
|     dir_hash_1 = prep_docker_build_folder( | ||||
|         temp_dir, | ||||
|         base_image='ubuntu:22.04', | ||||
|         base_image='nikolaik/python-nodejs:python3.11-nodejs22', | ||||
|         skip_init=False, | ||||
|     ) | ||||
|  | ||||
|     with tempfile.TemporaryDirectory() as temp_dir_2: | ||||
|         dir_hash_2 = prep_docker_build_folder( | ||||
|             temp_dir_2, | ||||
|             base_image='ubuntu:22.04', | ||||
|             base_image='nikolaik/python-nodejs:python3.11-nodejs22', | ||||
|             skip_init=True, | ||||
|         ) | ||||
|     assert dir_hash_1 != dir_hash_2 | ||||
| @@ -113,7 +113,7 @@ def test_hash_folder_diff_init(temp_dir): | ||||
| def test_hash_folder_diff_image(temp_dir): | ||||
|     dir_hash_1 = prep_docker_build_folder( | ||||
|         temp_dir, | ||||
|         base_image='ubuntu:22.04', | ||||
|         base_image='nikolaik/python-nodejs:python3.11-nodejs22', | ||||
|         skip_init=False, | ||||
|     ) | ||||
|  | ||||
| @@ -178,11 +178,12 @@ def test_get_runtime_image_repo_and_tag_eventstream(): | ||||
|         and img_tag == f'{OD_VERSION}_image_debian_tag_11' | ||||
|     ) | ||||
|  | ||||
|     base_image = 'ubuntu:22.04' | ||||
|     base_image = 'nikolaik/python-nodejs:python3.11-nodejs22' | ||||
|     img_repo, img_tag = get_runtime_image_repo_and_tag(base_image) | ||||
|     assert ( | ||||
|         img_repo == f'{RUNTIME_IMAGE_REPO}' | ||||
|         and img_tag == f'{OD_VERSION}_image_ubuntu_tag_22.04' | ||||
|         and img_tag | ||||
|         == f'{OD_VERSION}_image_nikolaik___python-nodejs_tag_python3.11-nodejs22' | ||||
|     ) | ||||
|  | ||||
|     base_image = 'ubuntu' | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Xingyao Wang
					Xingyao Wang