WARNING: THIS SITE IS A MIRROR OF GITHUB.COM / IT CANNOT LOGIN OR REGISTER ACCOUNTS / THE CONTENTS ARE PROVIDED AS-IS / THIS SITE ASSUMES NO RESPONSIBILITY FOR ANY DISPLAYED CONTENT OR LINKS / IF YOU FOUND SOMETHING MAY NOT GOOD FOR EVERYONE, CONTACT ADMIN AT ilovescratch@foxmail.com
Skip to content

Commit c611279

Browse files
[RuntimeEnv] Support custom podman command (#693)
* [RuntimeEnv] Support custom podman command * Fix empty env keys Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com> * fix * fix * Add test for output filter --------- Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
1 parent fd34b15 commit c611279

File tree

2 files changed

+66
-17
lines changed

2 files changed

+66
-17
lines changed

python/ray/_private/runtime_env/image_uri.py

Lines changed: 50 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import logging
22
import os
33
import json
4+
import shlex
45
from typing import List, Optional
56
import ray
67
import ray._private.runtime_env.constants as runtime_env_constants
@@ -26,22 +27,38 @@
2627
async def _create_impl(image_uri: str, logger: logging.Logger):
2728
# Pull image if it doesn't exist
2829
# Also get path to `default_worker.py` inside the image.
29-
pull_image_cmd = [
30-
"podman",
31-
"run",
32-
"--rm",
33-
image_uri,
34-
"python",
35-
"-c",
36-
(
37-
"import ray._private.workers.default_worker as default_worker; "
38-
"print(default_worker.__file__)"
39-
),
40-
]
41-
logger.info("Pulling image %s", image_uri)
42-
worker_path = await check_output_cmd(pull_image_cmd, logger=logger)
30+
custom_pull_cmd = os.getenv("RAY_PODMAN_PULL_CMD", "")
31+
if custom_pull_cmd:
32+
logger.info("Using custom pull command: %s", custom_pull_cmd)
33+
shell_cmd = ["sh", "-c", custom_pull_cmd]
34+
worker_path = await check_output_cmd(shell_cmd, logger=logger)
35+
else:
36+
pull_image_cmd = [
37+
"podman",
38+
"run",
39+
"--rm",
40+
image_uri,
41+
"python",
42+
"-c",
43+
(
44+
"import ray._private.workers.default_worker as default_worker; "
45+
"print(default_worker.__file__)"
46+
),
47+
]
48+
logger.info("Pulling image %s", image_uri)
49+
worker_path = await check_output_cmd(pull_image_cmd, logger=logger)
50+
51+
output_filter = os.getenv("RAY_PODMAN_OUTPUT_FILTER", "")
52+
if output_filter:
53+
worker_path = await _apply_output_filter(logger, worker_path, output_filter)
4354
return worker_path.strip()
4455

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

4663
def _modify_container_context_impl(
4764
runtime_env: "RuntimeEnv", # noqa: F821
@@ -157,9 +174,9 @@ def _modify_container_context_impl(
157174

158175
redirected_pyenv_folder = None
159176
if container_install_ray or container_pip_packages:
160-
container_to_host_mount_dict[
161-
container_dependencies_installer_path
162-
] = get_dependencies_installer_path()
177+
container_to_host_mount_dict[container_dependencies_installer_path] = (
178+
get_dependencies_installer_path()
179+
)
163180
if runtime_env_constants.RAY_PODMAN_UES_WHL_PACKAGE:
164181
container_to_host_mount_dict[get_ray_whl_dir()] = get_ray_whl_dir()
165182

@@ -253,6 +270,16 @@ def _modify_context_impl(
253270
ray_tmp_dir: str,
254271
):
255272
context.override_worker_entrypoint = worker_path
273+
custom_container_cmd = os.getenv("RAY_PODMAN_CONTAINER_CMD", "")
274+
if custom_container_cmd:
275+
custom_container_cmd_str = custom_container_cmd.format(
276+
ray_tmp_dir=ray_tmp_dir, image_uri=image_uri
277+
)
278+
logger.info(
279+
f"Starting worker in container with prefix {custom_container_cmd_str}"
280+
)
281+
context.py_executable = custom_container_cmd_str
282+
return
256283

257284
container_driver = "podman"
258285
container_command = [
@@ -285,6 +312,12 @@ def _modify_context_impl(
285312
if env_var_name.startswith("RAY_"):
286313
env_vars[env_var_name] = env_var_value
287314

315+
extra_env_keys = os.getenv("RAY_PODMAN_EXTRA_ENV_KEYS", "")
316+
if extra_env_keys:
317+
for key in (k.strip() for k in extra_env_keys.split(",")):
318+
if key and key in os.environ:
319+
env_vars[key] = os.environ[key]
320+
288321
# Support for runtime_env['env_vars']
289322
env_vars.update(context.env_vars)
290323

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import asyncio
2+
import logging
3+
from ray._private.runtime_env.image_uri import _apply_output_filter
4+
5+
6+
def test_apply_output_filter_with_grep_v_head():
7+
logger = logging.getLogger(__name__)
8+
worker_path = """time=1234567890
9+
/path/to/worker.py
10+
time=1234567891
11+
/other/path/file.py
12+
time=1234567892
13+
/final/path/worker.py"""
14+
15+
result = asyncio.run(_apply_output_filter(logger, worker_path, "grep -v '^time=' | head -1"))
16+
assert result.strip() == "/path/to/worker.py"

0 commit comments

Comments
 (0)