Skip to content
Open
Changes from 14 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 40 additions & 2 deletions scripts/release/build/image_build_process.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,20 @@
DEFAULT_BUILDER_NAME = "multiarch" # Default buildx builder name


def ensure_ecr_cache_repository(repository_name: str, region: str = "us-east-1"):
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if there is none - we should create the repo!

ecr_client = boto3.client("ecr", region_name=region)
try:
_ = ecr_client.create_repository(repositoryName=repository_name)
logger.info(f"Successfully created ECR cache repository: {repository_name}")
except ClientError as e:
error_code = e.response['Error']['Code']
if error_code == 'RepositoryAlreadyExistsException':
logger.info(f"ECR cache repository already exists: {repository_name}")
else:
logger.error(f"Failed to create ECR cache repository {repository_name}: {error_code} - {e}")
raise


def ecr_login_boto3(region: str, account_id: str):
"""
Fetches an auth token from ECR via boto3 and logs
Expand Down Expand Up @@ -75,8 +89,8 @@ def ensure_buildx_builder(builder_name: str = DEFAULT_BUILDER_NAME) -> str:
def execute_docker_build(
tag: str,
dockerfile: str,
path: str, args:
Dict[str, str],
path: str,
args: Dict[str, str],
push: bool,
platforms: list[str],
builder_name: str = DEFAULT_BUILDER_NAME,
Expand All @@ -102,11 +116,33 @@ def execute_docker_build(
# Convert build args to the format expected by python_on_whales
build_args = {k: str(v) for k, v in args.items()}

registry_name = tag.split(":")[0] if ":" in tag else tag
# e.g., "268558157000.dkr.ecr.us-east-1.amazonaws.com/dev/mongodb-kubernetes" -> "mongodb-kubernetes"
cache_image_name = registry_name.split("/")[-1]
# TODO CLOUDP-335471: use env variables to configure AWS region and account ID
cache_repo_name = f"dev/cache/{cache_image_name}"
cache_registry = f"268558157000.dkr.ecr.us-east-1.amazonaws.com/{cache_repo_name}"
cache_from = f"type=registry,ref={f"{cache_registry}:cache"}"

cache_to = {
"type": "registry",
"ref": f"{cache_registry}:cache",
"mode": "max",
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

max means we are caching all layers

"oci-mediatypes": "true",
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oci is the future

"image-manifest": "true"
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"""
By default, the OCI media type generates an image index for the cache image. Some OCI registries, such as Amazon ECR, don't support the image index media type: application/vnd.oci.image.index.v1+json. If you export cache images to ECR, or any other registry that doesn't support image indices, set the image-manifest parameter to true to generate a single image manifest instead of an image index for the cache image:
"""

}

ensure_ecr_cache_repository(cache_repo_name)

logger.info(f"Building image: {tag}")
logger.info(f"Platforms: {platforms}")
logger.info(f"Dockerfile: {dockerfile}")
logger.info(f"Build context: {path}")
logger.info(f"Cache registry: {cache_registry}")
logger.info(f"Cache to: {cache_to}")
logger.debug(f"Build args: {build_args}")
logger.debug(f"Cache from: {cache_from}")
logger.debug(f"Cache to: {cache_to}")

# Use buildx for multi-platform builds
if len(platforms) > 1:
Expand All @@ -124,6 +160,8 @@ def execute_docker_build(
push=push,
provenance=False, # To not get an untagged image for single platform builds
pull=False, # Don't always pull base images
cache_from=cache_from,
cache_to=cache_to,
)

logger.info(f"Successfully built {'and pushed' if push else ''} {tag}")
Expand Down