Skip to content

Commit d5c8a14

Browse files
committed
First script draft
1 parent 4efe405 commit d5c8a14

File tree

1 file changed

+131
-1
lines changed

1 file changed

+131
-1
lines changed

scripts/release/build_images.py

Lines changed: 131 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,131 @@
1-
# Methods responsible for building and pushing docker images.
1+
# Methods responsible for building and pushing docker images.
2+
import sys
3+
import traceback
4+
5+
import boto3
6+
from botocore.exceptions import BotoCoreError, ClientError
7+
import base64
8+
9+
from lib.base_logger import logger
10+
import docker
11+
12+
logger.info("Starting build images script")
13+
14+
IMAGE_NAME = "mongodb-kubernetes-operator"
15+
DOCKERFILES_PATH = f"./docker/{IMAGE_NAME}"
16+
CONTEXT_DOCKERFILE = "Dockerfile"
17+
RELEASE_DOCKERFILE = "Dockerfile.plain"
18+
STAGING_REGISTRY = "268558157000.dkr.ecr.us-east-1.amazonaws.com/julienben/operator-staging-temp"
19+
LATEST_TAG = "latest"
20+
LATEST_TAG_CONTEXT = f"{LATEST_TAG}-context"
21+
22+
def ecr_login_boto3(region: str, account_id: str):
23+
"""
24+
Fetches an auth token from ECR via boto3 and logs
25+
into the Docker daemon via the Docker SDK.
26+
"""
27+
registry = f"{account_id}.dkr.ecr.{region}.amazonaws.com"
28+
# 1) get token
29+
boto3.setup_default_session(profile_name='default')
30+
ecr = boto3.client("ecr", region_name=region)
31+
try:
32+
resp = ecr.get_authorization_token(registryIds=[account_id])
33+
except (BotoCoreError, ClientError) as e:
34+
raise RuntimeError(f"Failed to fetch ECR token: {e}")
35+
36+
auth_data = resp["authorizationData"][0]
37+
token = auth_data["authorizationToken"] # base64 of "AWS:password"
38+
username, password = base64.b64decode(token).decode().split(":", 1)
39+
40+
# 2) docker login
41+
client = docker.APIClient() # low-level client supports login()
42+
login_resp = client.login(
43+
username=username,
44+
password=password,
45+
registry=registry,
46+
reauth=True
47+
)
48+
# login_resp is a dict like {'Status': 'Login Succeeded'}
49+
status = login_resp.get("Status", "")
50+
if "Succeeded" not in status:
51+
raise RuntimeError(f"Docker login failed: {login_resp}")
52+
logger.info(f"ECR login succeeded: {status}")
53+
54+
def build_image(docker_client: docker.DockerClient, tag: str, dockerfile: str, path: str, args=None):
55+
"""
56+
Build a Docker image.
57+
58+
:param path: Build context path (directory with your Dockerfile)
59+
:param dockerfile: Name or relative path of the Dockerfile within `path`
60+
:param tag: Image tag (name:tag)
61+
"""
62+
63+
try:
64+
image, logs = docker_client.images.build(
65+
path=path,
66+
dockerfile=dockerfile,
67+
tag=tag,
68+
rm=True, # remove intermediate containers after a successful build
69+
pull=False, # set True to always attempt to pull a newer base image
70+
buildargs=args # pass build args if provided
71+
)
72+
logger.info(f"Successfully built {tag} (id: {image.id})")
73+
# Print build output
74+
for chunk in logs:
75+
if 'stream' in chunk:
76+
logger.debug(chunk['stream'])
77+
except docker.errors.BuildError as e:
78+
logger.error("Build failed:")
79+
for stage in e.build_log:
80+
if "stream" in stage:
81+
logger.debug(stage["stream"])
82+
elif "error" in stage:
83+
logger.error(stage["error"])
84+
logger.error(e)
85+
sys.exit(1)
86+
except Exception as e:
87+
logger.error(f"Unexpected error: {e}")
88+
sys.exit(2)
89+
90+
def push_image(docker_client: docker.DockerClient, image: str, tag: str):
91+
"""
92+
Push a Docker image to a registry.
93+
94+
:param image: Image name (e.g., 'my-image')
95+
:param tag: Image tag (e.g., 'latest')
96+
"""
97+
try:
98+
response = docker_client.images.push(image, tag=tag)
99+
logger.info(f"Successfully pushed {image}:{tag}")
100+
logger.debug(response)
101+
except docker.errors.APIError as e:
102+
logger.error(f"Failed to push image {image}:{tag} - {e}")
103+
sys.exit(1)
104+
105+
if __name__ == '__main__':
106+
docker_client = docker.from_env()
107+
logger.info("Docker client initialized")
108+
109+
# Login to ECR using boto3
110+
ecr_login_boto3(region='us-east-1', account_id='268558157000')
111+
112+
# Build context image
113+
image_full_tag = f"{STAGING_REGISTRY}:{LATEST_TAG_CONTEXT}"
114+
logger.info(f"Building image: {image_full_tag}")
115+
context_dockerfile_full_path = f"{DOCKERFILES_PATH}/{CONTEXT_DOCKERFILE}"
116+
logger.info(f"Using Dockerfile at: {context_dockerfile_full_path}")
117+
build_image(docker_client, path=".", dockerfile=context_dockerfile_full_path, tag=LATEST_TAG_CONTEXT, args={'version': '0.0.1'})
118+
119+
# Push to staging registry
120+
push_image(docker_client, STAGING_REGISTRY, LATEST_TAG_CONTEXT)
121+
122+
# Build release image
123+
release_image_full_tag = f'{STAGING_REGISTRY}:latest'
124+
release_dockerfile_full_path = f"{DOCKERFILES_PATH}/{RELEASE_DOCKERFILE}"
125+
logger.info(f"Building release image with tag: {release_image_full_tag}")
126+
logger.info(f"Using Dockerfile at: {release_dockerfile_full_path}")
127+
128+
build_image(docker_client, path=".", dockerfile=release_dockerfile_full_path, tag=release_image_full_tag, args={'imagebase': image_full_tag})
129+
130+
# Push release image
131+
push_image(docker_client, STAGING_REGISTRY, LATEST_TAG)

0 commit comments

Comments
 (0)