diff --git a/infra/build/functions/base_images.py b/infra/build/functions/base_images.py index 0df75b731a63..b1a90ff09132 100644 --- a/infra/build/functions/base_images.py +++ b/infra/build/functions/base_images.py @@ -47,6 +47,23 @@ # This version will receive the ':v1' tag. DEFAULT_VERSION = 'legacy' +# Defines the dependency graph for base images. +IMAGE_DEPENDENCIES = { + 'base-clang': ['base-image'], + 'base-clang-full': ['base-clang'], + 'base-builder': ['base-clang'], + 'base-builder-go': ['base-builder'], + 'base-builder-javascript': ['base-builder'], + 'base-builder-jvm': ['base-builder'], + 'base-builder-python': ['base-builder'], + 'base-builder-ruby': ['base-builder'], + 'base-builder-rust': ['base-builder'], + 'base-builder-swift': ['base-builder'], + 'base-runner': ['base-image', 'base-builder'], + 'base-runner-debug': ['base-runner'], + 'indexer': ['base-clang-full'], +} + class ImageConfig: """Configuration for a specific base image version.""" @@ -85,6 +102,8 @@ def _resolve_dockerfile(self) -> str: if os.path.exists(versioned_dockerfile): logging.info('Using versioned Dockerfile: %s', versioned_dockerfile) return versioned_dockerfile + raise FileNotFoundError( + f'Versioned Dockerfile not found for {self.name}:{self.version}') legacy_dockerfile = os.path.join(self.path, 'Dockerfile') logging.info('Using legacy Dockerfile: %s', legacy_dockerfile) @@ -156,6 +175,8 @@ def full_image_name_with_tag(self) -> str: def get_base_image_steps(images: Sequence[ImageConfig]) -> list[dict]: """Returns build steps for a given list of image configurations.""" steps = [build_lib.get_git_clone_step()] + build_ids = {} + for image_config in images: # The final tag is ':v1' for the default version, or the version name # (e.g., ':ubuntu-24-04') for others. @@ -167,11 +188,20 @@ def get_base_image_steps(images: Sequence[ImageConfig]) -> list[dict]: tags.append(f'{IMAGE_NAME_PREFIX}{image_config.name}:latest') dockerfile_path = os.path.join('oss-fuzz', image_config.dockerfile_path) - steps.append( - build_lib.get_docker_build_step(tags, - image_config.path, - dockerfile_path=dockerfile_path, - build_args=image_config.build_args)) + step = build_lib.get_docker_build_step(tags, + image_config.path, + dockerfile_path=dockerfile_path, + build_args=image_config.build_args) + + # Check for dependencies and add 'waitFor' if necessary. + dependencies = IMAGE_DEPENDENCIES.get(image_config.name, []) + wait_for = [build_ids[dep] for dep in dependencies if dep in build_ids] + if wait_for: + step['waitFor'] = wait_for + + build_ids[image_config.name] = step['id'] + steps.append(step) + return steps