205 lines
5.7 KiB
Python
205 lines
5.7 KiB
Python
import os
|
|
import subprocess
|
|
import sys
|
|
import tempfile
|
|
from typing import Dict, List, Optional
|
|
|
|
from ray_release.byod.build_context import BuildContext, fill_build_context_dir
|
|
from ray_release.config import RELEASE_PACKAGE_DIR
|
|
from ray_release.logger import logger
|
|
from ray_release.test import (
|
|
Test,
|
|
)
|
|
|
|
# AZURE_REGISTRY_NAME import temporarily removed below: Azure image push is
|
|
# disabled due to CI issues. Re-add `AZURE_REGISTRY_NAME` to the import below
|
|
# when re-enabling the Azure tag/push block in build_anyscale_custom_byod_image.
|
|
from ray_release.util import ANYSCALE_RAY_IMAGE_PREFIX
|
|
|
|
bazel_workspace_dir = os.environ.get("BUILD_WORKSPACE_DIRECTORY", "")
|
|
|
|
|
|
def build_anyscale_custom_byod_image(
|
|
image: str,
|
|
base_image: str,
|
|
build_context: BuildContext,
|
|
release_byod_dir: Optional[str] = None,
|
|
) -> None:
|
|
if _image_exist(image):
|
|
logger.info(f"Image {image} already exists")
|
|
return
|
|
|
|
if not release_byod_dir:
|
|
if bazel_workspace_dir:
|
|
release_byod_dir = os.path.join(
|
|
bazel_workspace_dir, "release/ray_release/byod"
|
|
)
|
|
else:
|
|
release_byod_dir = os.path.join(RELEASE_PACKAGE_DIR, "ray_release/byod")
|
|
|
|
with tempfile.TemporaryDirectory() as build_dir:
|
|
fill_build_context_dir(build_context, release_byod_dir, build_dir)
|
|
|
|
docker_build_cmd = "docker build --progress=plain .".split()
|
|
docker_build_cmd += ["--build-arg", f"BASE_IMAGE={base_image}"]
|
|
docker_build_cmd += ["-t", image]
|
|
|
|
env = os.environ.copy()
|
|
env["DOCKER_BUILDKIT"] = "1"
|
|
|
|
subprocess.check_call(
|
|
docker_build_cmd,
|
|
stdout=sys.stderr,
|
|
cwd=build_dir,
|
|
env=env,
|
|
)
|
|
|
|
if not base_image.startswith(ANYSCALE_RAY_IMAGE_PREFIX):
|
|
_check_ray_commit_in_image(image)
|
|
|
|
_push_image(image)
|
|
if os.environ.get("BUILDKITE"):
|
|
subprocess.run(
|
|
[
|
|
"buildkite-agent",
|
|
"annotate",
|
|
"--style=info",
|
|
"--context=custom-images",
|
|
"--append",
|
|
f"{image}<br/>",
|
|
],
|
|
)
|
|
# Azure tag-and-push for custom BYOD images temporarily disabled due to
|
|
# CI issues.
|
|
logger.info(
|
|
"Skipping Azure ACR tag/push for custom BYOD image %s: Azure image "
|
|
"push is temporarily disabled due to CI issues.",
|
|
image,
|
|
)
|
|
# tag_without_registry = image.split("/")[-1]
|
|
# azure_tag = f"{AZURE_REGISTRY_NAME}.azurecr.io/{tag_without_registry}"
|
|
# _tag_and_push(source=image, target=azure_tag)
|
|
|
|
|
|
def build_anyscale_base_byod_images(tests: List[Test]) -> List[str]:
|
|
"""
|
|
Builds the Anyscale BYOD images for the given tests.
|
|
"""
|
|
images = set()
|
|
for test in tests:
|
|
images.add(test.get_anyscale_base_byod_image())
|
|
|
|
image_list = list(images)
|
|
image_list.sort()
|
|
|
|
for image in image_list:
|
|
if not _image_exist(image):
|
|
raise RuntimeError(f"Image {image} not found")
|
|
|
|
return image_list
|
|
|
|
|
|
def _check_ray_commit_in_image(byod_image: str) -> None:
|
|
docker_ray_commit = (
|
|
subprocess.check_output(
|
|
[
|
|
"docker",
|
|
"run",
|
|
"-ti",
|
|
"--entrypoint",
|
|
"python",
|
|
byod_image,
|
|
"-c",
|
|
"import ray; print(ray.__commit__)",
|
|
],
|
|
)
|
|
.decode("utf-8")
|
|
.strip()
|
|
)
|
|
if os.environ.get("RAY_IMAGE_TAG"):
|
|
logger.info(f"Ray commit from image: {docker_ray_commit}")
|
|
else:
|
|
expected_ray_commit = _get_ray_commit()
|
|
assert (
|
|
docker_ray_commit == expected_ray_commit
|
|
), f"Expected ray commit {expected_ray_commit}, found {docker_ray_commit}"
|
|
|
|
|
|
def _push_image(byod_image: str) -> None:
|
|
logger.info(f"Pushing image to registry: {byod_image}")
|
|
subprocess.check_call(
|
|
["docker", "push", byod_image],
|
|
stdout=sys.stderr,
|
|
)
|
|
|
|
|
|
def _validate_and_push(byod_image: str) -> None:
|
|
"""
|
|
Validates the given image and pushes it to ECR.
|
|
"""
|
|
docker_ray_commit = (
|
|
subprocess.check_output(
|
|
[
|
|
"docker",
|
|
"run",
|
|
"-ti",
|
|
"--entrypoint",
|
|
"python",
|
|
byod_image,
|
|
"-c",
|
|
"import ray; print(ray.__commit__)",
|
|
],
|
|
)
|
|
.decode("utf-8")
|
|
.strip()
|
|
)
|
|
if os.environ.get("RAY_IMAGE_TAG"):
|
|
logger.info(f"Ray commit from image: {docker_ray_commit}")
|
|
else:
|
|
expected_ray_commit = _get_ray_commit()
|
|
assert (
|
|
docker_ray_commit == expected_ray_commit
|
|
), f"Expected ray commit {expected_ray_commit}, found {docker_ray_commit}"
|
|
logger.info(f"Pushing image to registry: {byod_image}")
|
|
subprocess.check_call(
|
|
["docker", "push", byod_image],
|
|
stdout=sys.stderr,
|
|
)
|
|
|
|
|
|
def _get_ray_commit(envs: Optional[Dict[str, str]] = None) -> str:
|
|
if envs is None:
|
|
envs = os.environ
|
|
for key in [
|
|
"RAY_WANT_COMMIT_IN_IMAGE",
|
|
"COMMIT_TO_TEST",
|
|
"BUILDKITE_COMMIT",
|
|
]:
|
|
commit = envs.get(key, "")
|
|
if commit:
|
|
return commit
|
|
return ""
|
|
|
|
|
|
def _image_exist(image: str) -> bool:
|
|
"""
|
|
Checks if the given image exists in Docker
|
|
"""
|
|
p = subprocess.run(
|
|
["docker", "manifest", "inspect", image],
|
|
stdout=sys.stderr,
|
|
stderr=sys.stderr,
|
|
)
|
|
return p.returncode == 0
|
|
|
|
|
|
def _tag_and_push(source: str, target: str) -> None:
|
|
subprocess.check_call(
|
|
["docker", "tag", source, target],
|
|
stdout=sys.stderr,
|
|
)
|
|
subprocess.check_call(
|
|
["docker", "push", target],
|
|
stdout=sys.stderr,
|
|
)
|