mirror of
https://github.com/saymrwulf/onnxruntime.git
synced 2026-05-14 20:48:00 +00:00
### Description Improve docker commands to make docker image layer caching works. It can make docker building faster and more stable. So far, A100 pool's system disk is too small to use docker cache. We won't use pipeline cache for docker image and remove some legacy code. ### Motivation and Context There are often an exception of ``` 64.58 + curl https://nodejs.org/dist/v18.17.1/node-v18.17.1-linux-x64.tar.gz -sSL --retry 5 --retry-delay 30 --create-dirs -o /tmp/src/node-v18.17.1-linux-x64.tar.gz --fail 286.4 curl: (92) HTTP/2 stream 0 was not closed cleanly: INTERNAL_ERROR (err 2) ``` Because Onnxruntime pipeline have been sending too many requests to download Nodejs in docker building. Which is the major reason of pipeline failing now In fact, docker image layer caching never works. We can always see the scrips are still running ``` #9 [3/5] RUN cd /tmp/scripts && /tmp/scripts/install_centos.sh && /tmp/scripts/install_deps.sh && rm -rf /tmp/scripts #9 0.234 /bin/sh: warning: setlocale: LC_ALL: cannot change locale (en_US.UTF-8) #9 0.235 /bin/sh: warning: setlocale: LC_ALL: cannot change locale (en_US.UTF-8) #9 0.235 /tmp/scripts/install_centos.sh: line 1: !/bin/bash: No such file or directory #9 0.235 ++ '[' '!' -f /etc/yum.repos.d/microsoft-prod.repo ']' #9 0.236 +++ tr -dc 0-9. #9 0.236 +++ cut -d . -f1 #9 0.238 ++ os_major_version=8 .... #9 60.41 + curl https://nodejs.org/dist/v18.17.1/node-v18.17.1-linux-x64.tar.gz -sSL --retry 5 --retry-delay 30 --create-dirs -o /tmp/src/node-v18.17.1-linux-x64.tar.gz --fail #9 60.59 + return 0 ... ``` This PR is improving the docker command to make image layer caching work. Thus, CI won't send so many redundant request of downloading NodeJS. ``` #9 [2/5] ADD scripts /tmp/scripts #9 CACHED #10 [3/5] RUN cd /tmp/scripts && /tmp/scripts/install_centos.sh && /tmp/scripts/install_deps.sh && rm -rf /tmp/scripts #10 CACHED #11 [4/5] RUN adduser --uid 1000 onnxruntimedev #11 CACHED #12 [5/5] WORKDIR /home/onnxruntimedev #12 CACHED ``` ###Reference https://docs.docker.com/build/drivers/ --------- Co-authored-by: Yi Zhang <your@email.com>
147 lines
4.9 KiB
Python
Executable file
147 lines
4.9 KiB
Python
Executable file
#!/usr/bin/env python3
|
|
# Copyright (c) Microsoft Corporation. All rights reserved.
|
|
# Licensed under the MIT License.
|
|
|
|
import argparse
|
|
import os
|
|
import shlex
|
|
import shutil
|
|
import sys
|
|
from pathlib import Path
|
|
|
|
from logger import get_logger
|
|
|
|
SCRIPT_DIR = os.path.dirname(os.path.realpath(__file__))
|
|
REPO_DIR = os.path.normpath(os.path.join(SCRIPT_DIR, "..", ".."))
|
|
sys.path.append(os.path.join(REPO_DIR, "tools", "python"))
|
|
from util import run # noqa: E402
|
|
|
|
log = get_logger("get_docker_image")
|
|
|
|
|
|
def parse_args():
|
|
parser = argparse.ArgumentParser(
|
|
description="Build a docker image and push it to a remote Azure Container Registry."
|
|
"The content in the remote registry can be used as a cache when we need to build the thing again."
|
|
"The user must be logged in to the container registry."
|
|
)
|
|
|
|
parser.add_argument("--dockerfile", default="Dockerfile", help="Path to the Dockerfile.")
|
|
parser.add_argument("--context", default=".", help="Path to the build context.")
|
|
parser.add_argument(
|
|
"--docker-build-args", default="", help="Arguments that will be passed to the 'docker build' command."
|
|
)
|
|
|
|
parser.add_argument(
|
|
"--container-registry",
|
|
help="The Azure container registry name. If not provided, no container registry will be used.",
|
|
)
|
|
parser.add_argument("--repository", required=True, help="The image repository name.")
|
|
|
|
parser.add_argument("--use_imagecache", action="store_true", help="use cached image in pipeline cache")
|
|
|
|
parser.add_argument("--docker-path", default="docker", help="Path to docker.")
|
|
|
|
parser.add_argument("--manylinux-src", default="manylinux", help="Path to manylinux src folder")
|
|
|
|
parser.add_argument(
|
|
"--multiple_repos",
|
|
action="store_true",
|
|
help="used in packaging pipeline, which couldn't use get-docker-images-steps.yml",
|
|
)
|
|
|
|
return parser.parse_args()
|
|
|
|
|
|
def main():
|
|
args = parse_args()
|
|
|
|
log.debug(f"Dockerfile: {args.dockerfile}, context: {args.context}, docker build args: '{args.docker_build_args}'")
|
|
|
|
use_container_registry = args.container_registry is not None
|
|
|
|
if not use_container_registry:
|
|
log.info("No container registry will be used")
|
|
|
|
full_image_name = (
|
|
f"{args.container_registry}.azurecr.io/{args.repository}:latest"
|
|
if use_container_registry
|
|
else f"{args.repository}:latest"
|
|
)
|
|
|
|
log.info(f"Image: {full_image_name}")
|
|
|
|
dst_deps_file = Path(args.context) / "scripts" / "deps.txt"
|
|
# The docker file may provide a special deps.txt in its docker context dir and uses that one.
|
|
# Otherwise, copy a generic one from this repo's cmake dir.
|
|
if not dst_deps_file.exists():
|
|
log.info(f"Copy deps.txt to : {dst_deps_file}")
|
|
shutil.copyfile(Path(REPO_DIR) / "cmake" / "deps.txt", str(dst_deps_file))
|
|
|
|
if "manylinux" in args.dockerfile and args.multiple_repos:
|
|
manylinux_build_scripts_folder = Path(args.manylinux_src) / "docker" / "build_scripts"
|
|
dest = Path(args.context) / "build_scripts"
|
|
if dest.exists():
|
|
log.info(f"Deleting: {dest!s}")
|
|
shutil.rmtree(str(dest))
|
|
shutil.copytree(str(manylinux_build_scripts_folder), str(dest))
|
|
src_entrypoint_file = str(Path(args.manylinux_src) / "docker" / "manylinux-entrypoint")
|
|
dst_entrypoint_file = str(Path(args.context) / "manylinux-entrypoint")
|
|
shutil.copyfile(src_entrypoint_file, dst_entrypoint_file)
|
|
shutil.copymode(src_entrypoint_file, dst_entrypoint_file)
|
|
run(
|
|
"patch",
|
|
"-p1",
|
|
"-i",
|
|
str((Path(SCRIPT_DIR) / "github" / "linux" / "docker" / "manylinux.patch").resolve()),
|
|
cwd=str(dest),
|
|
)
|
|
|
|
if use_container_registry:
|
|
run(args.docker_path, "buildx", "create", "--driver=docker-container", "--name=container_builder")
|
|
run(
|
|
args.docker_path,
|
|
"--log-level",
|
|
"error",
|
|
"buildx",
|
|
"build",
|
|
"--load",
|
|
"--tag",
|
|
full_image_name,
|
|
"--cache-from=type=registry,ref=" + full_image_name,
|
|
"--builder",
|
|
"container_builder",
|
|
"--build-arg",
|
|
"BUILDKIT_INLINE_CACHE=1",
|
|
*shlex.split(args.docker_build_args),
|
|
"-f",
|
|
args.dockerfile,
|
|
args.context,
|
|
)
|
|
run(
|
|
args.docker_path,
|
|
"push",
|
|
full_image_name,
|
|
)
|
|
else:
|
|
log.info("Building image...")
|
|
run(
|
|
args.docker_path,
|
|
"build",
|
|
"--pull",
|
|
*shlex.split(args.docker_build_args),
|
|
"--tag",
|
|
full_image_name,
|
|
"--file",
|
|
args.dockerfile,
|
|
args.context,
|
|
)
|
|
|
|
# tag so we can refer to the image by repository name
|
|
run(args.docker_path, "tag", full_image_name, args.repository)
|
|
|
|
return 0
|
|
|
|
|
|
if __name__ == "__main__":
|
|
sys.exit(main())
|