in scripts/azureml-assets/azureml/assets/environment/build.py [0:0]
def build_images(input_dirs: List[Path],
asset_config_filename: str,
output_directory: Path,
build_logs_dir: Path,
pin_versions: bool,
max_parallel: int,
changed_files: List[Path],
tag_with_version: bool,
os_to_build: assets.Os = None,
resource_group: str = None,
registry: str = None,
test_command: str = None,
push: bool = False,
use_version_dirs: bool = False,
trivy_url: str = None) -> bool:
"""Build Docker images in parallel, either locally or via ACR.
Args:
input_dirs (List[Path]): Input directories where environments are located.
asset_config_filename (str): Asset config filename to search for.
output_directory (Path): Directory to which assets successfully built will be copied.
build_logs_dir (Path): Directory to receive build logs.
pin_versions (bool): Pin image versions.
max_parallel (int): Maximum number of images to build in parallel.
changed_files (List[Path]): List of changed files, used to filter environments.
tag_with_version (bool): Tag image with asset version.
os_to_build (assets.Os, optional): Operating system to build on via ACR. Defaults to None.
resource_group (str, optional): Resource group name for ACR builds. Defaults to None.
registry (str, optional): ACR name. Defaults to None.
test_command (str, optional): Command used to test images. Defaults to None.
push (bool, optional): Push images to ACR. Defaults to False.
use_version_dirs (bool, optional): Use version directories for output. Defaults to False.
trivy_url (str, optional): URL to download Trivy for vulnerability scanning. Defaults to None.
Returns:
bool: True if all images were build successfully, otherwise False.
"""
counters = Counter()
with ThreadPoolExecutor(max_parallel) as pool:
# Find environments under image root directories
futures = []
for asset_config in util.find_assets(input_dirs, asset_config_filename, assets.AssetType.ENVIRONMENT,
changed_files):
env_config = asset_config.extra_config_as_object()
# Filter by OS
if os_to_build and env_config.os != os_to_build:
logger.print(f"Skipping build of image for {asset_config.name}: "
f"Operating system {env_config.os.value} != {os_to_build.value}")
continue
# Pin versions
if pin_versions:
try:
assets.pin_env_files(env_config)
except Exception as e:
logger.log_error(f"Failed to pin versions for {asset_config.name}: {e}")
counters[FAILED_COUNT] += 1
continue
# Skip environments without build context
if not env_config.build_enabled:
logger.print(f"Skipping build of image for {asset_config.name}: No build context specified")
# Copy file to output directory without building
if output_directory:
util.copy_asset_to_output_dir(asset_config=asset_config, output_directory=output_directory,
add_subdir=True, use_version_dir=use_version_dirs)
continue
# Don't push environments that aren't published
push_this_image = push and env_config.publish_enabled
if push and not push_this_image:
logger.print(f"Skipping push of image for {asset_config.name}: Not published")
# Tag with version from spec
if tag_with_version:
version = asset_config.version
image_name = env_config.get_image_name_with_tag(version)
else:
image_name = env_config.image_name
# Start building image
build_log = build_logs_dir / f"{asset_config.name}.log"
futures.append(pool.submit(build_image, asset_config=asset_config, env_config=env_config,
image_name=image_name, build_log=build_log, resource_group=resource_group,
registry=registry, test_command=test_command, push=push_this_image,
trivy_url=trivy_url))
# Wait for builds to complete
built_images = []
for future in as_completed(futures):
(asset_config, image_name, return_code, output) = future.result()
logger.start_group(f"{asset_config.name} build log")
logger.print(output)
logger.end_group()
if return_code != 0:
logger.log_error(f"Build of image for {asset_config.name} failed with exit status {return_code}",
"Build failure")
counters[FAILED_COUNT] += 1
else:
logger.log_debug(f"Successfully built image for {asset_config.name}")
counters[SUCCESS_COUNT] += 1
built_images.append(image_name)
if output_directory:
util.copy_asset_to_output_dir(asset_config=asset_config, output_directory=output_directory,
add_subdir=True, use_version_dir=use_version_dirs)
# Set variables
for counter_name in COUNTERS:
logger.set_output(counter_name, counters[counter_name])
logger.set_output(BUILT_IMAGES, ",".join(built_images))
if counters[FAILED_COUNT] > 0:
logger.log_error(f"{counters[FAILED_COUNT]} environment image(s) failed to build")
return False
return True