Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions build-docker-ant.sh
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
# shellcheck disable=SC2086
# This script is for users to build docker images locally. It is most useful for users wishing to edit the
# base-deps, or ray images. This script is *not* tested.
# A pre-built image example, constructed following build-docker-ant.sh, is available on Alibaba Cloud Container Registry:
# crpi-3wcszgxf0r7f5bmh.cn-hangzhou.personal.cr.aliyuncs.com/ant-ray/prebuilt
Comment on lines +5 to +6

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Thank you for adding this. To prevent any potential confusion for users, it would be beneficial to explicitly state that the Docker image is unofficial and hosted on a personal registry. The current phrasing is a bit ambiguous and users might assume it's an officially maintained image, which could be problematic for long-term support and reliability.

Suggested change
# A pre-built image example, constructed following build-docker-ant.sh, is available on Alibaba Cloud Container Registry:
# crpi-3wcszgxf0r7f5bmh.cn-hangzhou.personal.cr.aliyuncs.com/ant-ray/prebuilt
# An unofficial pre-built image example is available on a personal Alibaba Cloud Container Registry:
# crpi-3wcszgxf0r7f5bmh.cn-hangzhou.personal.cr.aliyuncs.com/ant-ray/prebuilt


GPU=""
BASE_IMAGE="ubuntu:22.04"
Expand Down
67 changes: 50 additions & 17 deletions python/ray/_private/runtime_env/image_uri.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import logging
import os
import json
import shlex
from typing import List, Optional
import ray
import ray._private.runtime_env.constants as runtime_env_constants
Expand All @@ -26,22 +27,38 @@
async def _create_impl(image_uri: str, logger: logging.Logger):
# Pull image if it doesn't exist
# Also get path to `default_worker.py` inside the image.
pull_image_cmd = [
"podman",
"run",
"--rm",
image_uri,
"python",
"-c",
(
"import ray._private.workers.default_worker as default_worker; "
"print(default_worker.__file__)"
),
]
logger.info("Pulling image %s", image_uri)
worker_path = await check_output_cmd(pull_image_cmd, logger=logger)
custom_pull_cmd = os.getenv("RAY_PODMAN_PULL_CMD", "")
if custom_pull_cmd:
logger.info("Using custom pull command: %s", custom_pull_cmd)
shell_cmd = ["sh", "-c", custom_pull_cmd]
worker_path = await check_output_cmd(shell_cmd, logger=logger)
else:
pull_image_cmd = [
"podman",
"run",
"--rm",
image_uri,
"python",
"-c",
(
"import ray._private.workers.default_worker as default_worker; "
"print(default_worker.__file__)"
),
]
logger.info("Pulling image %s", image_uri)
worker_path = await check_output_cmd(pull_image_cmd, logger=logger)

output_filter = os.getenv("RAY_PODMAN_OUTPUT_FILTER", "")
if output_filter:
worker_path = await _apply_output_filter(logger, worker_path, output_filter)
return worker_path.strip()

async def _apply_output_filter(logger, worker_path, output_filter):
safe_worker_path = shlex.quote(worker_path)
filter_cmd = ["sh", "-c", f"printf '%s' {safe_worker_path} | {output_filter}"]
filtered_path = await check_output_cmd(filter_cmd, logger=logger)
worker_path = filtered_path
return worker_path

def _modify_container_context_impl(
runtime_env: "RuntimeEnv", # noqa: F821
Expand Down Expand Up @@ -157,9 +174,9 @@ def _modify_container_context_impl(

redirected_pyenv_folder = None
if container_install_ray or container_pip_packages:
container_to_host_mount_dict[
container_dependencies_installer_path
] = get_dependencies_installer_path()
container_to_host_mount_dict[container_dependencies_installer_path] = (
get_dependencies_installer_path()
)
if runtime_env_constants.RAY_PODMAN_UES_WHL_PACKAGE:
container_to_host_mount_dict[get_ray_whl_dir()] = get_ray_whl_dir()

Expand Down Expand Up @@ -253,6 +270,16 @@ def _modify_context_impl(
ray_tmp_dir: str,
):
context.override_worker_entrypoint = worker_path
custom_container_cmd = os.getenv("RAY_PODMAN_CONTAINER_CMD", "")
if custom_container_cmd:
custom_container_cmd_str = custom_container_cmd.format(
ray_tmp_dir=ray_tmp_dir, image_uri=image_uri
)
logger.info(
f"Starting worker in container with prefix {custom_container_cmd_str}"
)
context.py_executable = custom_container_cmd_str
return

container_driver = "podman"
container_command = [
Expand Down Expand Up @@ -285,6 +312,12 @@ def _modify_context_impl(
if env_var_name.startswith("RAY_"):
env_vars[env_var_name] = env_var_value

extra_env_keys = os.getenv("RAY_PODMAN_EXTRA_ENV_KEYS", "")
if extra_env_keys:
for key in (k.strip() for k in extra_env_keys.split(",")):
if key and key in os.environ:
env_vars[key] = os.environ[key]

# Support for runtime_env['env_vars']
env_vars.update(context.env_vars)

Expand Down
16 changes: 16 additions & 0 deletions python/ray/tests/runtime_env_container/test_image_uri.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import asyncio
import logging
from ray._private.runtime_env.image_uri import _apply_output_filter


def test_apply_output_filter_with_grep_v_head():
logger = logging.getLogger(__name__)
worker_path = """time=1234567890
/path/to/worker.py
time=1234567891
/other/path/file.py
time=1234567892
/final/path/worker.py"""

result = asyncio.run(_apply_output_filter(logger, worker_path, "grep -v '^time=' | head -1"))
assert result.strip() == "/path/to/worker.py"