|
5 | 5 | from typing import Iterable, Literal, Mapping, NamedTuple, TypeVar |
6 | 6 |
|
7 | 7 | from shrub.v3.evg_build_variant import BuildVariant |
8 | | -from shrub.v3.evg_command import BuiltInCommand, EvgCommandType, subprocess_exec |
| 8 | +from shrub.v3.evg_command import ( |
| 9 | + BuiltInCommand, |
| 10 | + EvgCommandType, |
| 11 | + KeyValueParam, |
| 12 | + ec2_assume_role, |
| 13 | + expansions_update, |
| 14 | + subprocess_exec, |
| 15 | +) |
9 | 16 | from shrub.v3.evg_task import EvgTask, EvgTaskRef |
10 | 17 |
|
| 18 | +from config_generator.etc.function import Function |
| 19 | + |
11 | 20 | from ..etc.utils import all_possible |
12 | 21 |
|
13 | 22 | T = TypeVar("T") |
|
38 | 47 | "Valid options for the SASL configuration parameter" |
39 | 48 | TLSOption = Literal["OpenSSL", "off"] |
40 | 49 | "Options for the TLS backend configuration parameter (AKA 'ENABLE_SSL')" |
41 | | -CxxVersion = Literal["none"] # TODO: Once CXX-3103 is released, add latest C++ release tag. |
| 50 | +CxxVersion = Literal["none"] # TODO: Once CXX-3103 is released, add latest C++ release tag. |
42 | 51 | "C++ driver refs that are under CI test" |
43 | 52 |
|
44 | 53 | # A separator character, since we cannot use whitespace |
@@ -136,6 +145,34 @@ def suffix(self) -> str: |
136 | 145 | return _SEPARATOR.join(f"{k}={v}" for k, v in self._asdict().items()) |
137 | 146 |
|
138 | 147 |
|
| 148 | +# Authenticate with DevProd-provided Amazon ECR instance to use as pull-through cache for DockerHub. |
| 149 | +class DockerLoginAmazonECR(Function): |
| 150 | + name = 'docker-login-amazon-ecr' |
| 151 | + commands = [ |
| 152 | + # Avoid inadvertently using a pre-existing and potentially conflicting Docker config. |
| 153 | + expansions_update(updates=[KeyValueParam(key='DOCKER_CONFIG', value='${workdir}/.docker')]), |
| 154 | + ec2_assume_role(role_arn="arn:aws:iam::901841024863:role/ecr-role-evergreen-ro"), |
| 155 | + subprocess_exec( |
| 156 | + binary="bash", |
| 157 | + command_type=EvgCommandType.SETUP, |
| 158 | + include_expansions_in_env=[ |
| 159 | + "AWS_ACCESS_KEY_ID", |
| 160 | + "AWS_SECRET_ACCESS_KEY", |
| 161 | + "AWS_SESSION_TOKEN", |
| 162 | + "DOCKER_CONFIG", |
| 163 | + ], |
| 164 | + args=[ |
| 165 | + "-c", |
| 166 | + 'aws ecr get-login-password --region us-east-1 | docker login --username AWS --password-stdin 901841024863.dkr.ecr.us-east-1.amazonaws.com', |
| 167 | + ], |
| 168 | + ), |
| 169 | + ] |
| 170 | + |
| 171 | + @classmethod |
| 172 | + def call(cls, **kwargs): |
| 173 | + return cls.default_call(**kwargs) |
| 174 | + |
| 175 | + |
139 | 176 | def task_filter(env: EarthlyVariant, conf: Configuration) -> bool: |
140 | 177 | """ |
141 | 178 | Control which tasks are actually defined by matching on the platform and |
@@ -170,11 +207,16 @@ def earthly_exec( |
170 | 207 | return subprocess_exec( |
171 | 208 | "./tools/earthly.sh", |
172 | 209 | args=[ |
| 210 | + # Use Amazon ECR as pull-through cache for DockerHub to avoid rate limits. |
| 211 | + "--buildkit-image=901841024863.dkr.ecr.us-east-1.amazonaws.com/dockerhub/earthly/buildkitd:v0.8.3", |
173 | 212 | *(f"--secret={k}" for k in (secrets or ())), |
174 | 213 | f"+{target}", |
| 214 | + # Use Amazon ECR as pull-through cache for DockerHub to avoid rate limits. |
| 215 | + "--default_search_registry=901841024863.dkr.ecr.us-east-1.amazonaws.com/dockerhub", |
175 | 216 | *(f"--{arg}={val}" for arg, val in (args or {}).items()), |
176 | 217 | ], |
177 | 218 | command_type=EvgCommandType(kind), |
| 219 | + include_expansions_in_env=["DOCKER_CONFIG"], |
178 | 220 | env=env if env else None, |
179 | 221 | working_dir="mongoc", |
180 | 222 | ) |
@@ -209,15 +251,7 @@ def earthly_task( |
209 | 251 | return EvgTask( |
210 | 252 | name=name, |
211 | 253 | commands=[ |
212 | | - # Ensure subsequent Docker commands are authenticated. |
213 | | - subprocess_exec( |
214 | | - binary="bash", |
215 | | - command_type=EvgCommandType.SETUP, |
216 | | - args=[ |
217 | | - "-c", |
218 | | - r'docker login -u "${artifactory_username}" --password-stdin artifactory.corp.mongodb.com <<<"${artifactory_password}"', |
219 | | - ], |
220 | | - ), |
| 254 | + DockerLoginAmazonECR.call(), |
221 | 255 | # First, just build the "env-warmup" which will prepare the build environment. |
222 | 256 | # This won't generate any output, but allows EVG to track it as a separate build step |
223 | 257 | # for timing and logging purposes. The subequent build step will cache-hit the |
@@ -249,6 +283,10 @@ def earthly_task( |
249 | 283 | ] |
250 | 284 |
|
251 | 285 |
|
| 286 | +def functions(): |
| 287 | + return DockerLoginAmazonECR.defn() |
| 288 | + |
| 289 | + |
252 | 290 | def tasks() -> Iterable[EvgTask]: |
253 | 291 | for conf in all_possible(Configuration): |
254 | 292 | # test-example is a target in all configurations |
|
0 commit comments