Skip to content

Commit c843503

Browse files
tpryanivanmkc
andauthored
feat: adding build image to deploy cloud_run options (#2502)
* feat: adding build image to deploy cloud_run options Gives the ability for a user to set the build image for the deployment step to Cloud Run. Currently it is hard coded to python:3.11-slim, and this is still the default, but this allows that value to be overriden. * fix: applied formatting scripts testing: Added tests to ensure the behavior of the cli remains consistent with when used or omitted. * chore: next time run the formatter before you commit. --------- Co-authored-by: Ivan Cheung <[email protected]>
1 parent a2b7909 commit c843503

File tree

3 files changed

+94
-1
lines changed

3 files changed

+94
-1
lines changed

src/google/adk/cli/cli_deploy.py

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,10 @@
2121
import click
2222
from packaging.version import parse
2323

24+
BASE_BUILD_IMAGE = 'python:3.11-slim'
25+
2426
_DOCKERFILE_TEMPLATE = """
25-
FROM python:3.11-slim
27+
FROM {build_image}
2628
WORKDIR /app
2729
2830
# Create a non-root user
@@ -130,6 +132,7 @@ def to_cloud_run(
130132
session_service_uri: Optional[str] = None,
131133
artifact_service_uri: Optional[str] = None,
132134
memory_service_uri: Optional[str] = None,
135+
build_image: Optional[str] = BASE_BUILD_IMAGE,
133136
a2a: bool = False,
134137
):
135138
"""Deploys an agent to Google Cloud Run.
@@ -163,6 +166,7 @@ def to_cloud_run(
163166
session_service_uri: The URI of the session service.
164167
artifact_service_uri: The URI of the artifact service.
165168
memory_service_uri: The URI of the memory service.
169+
build_image: The image to use for building the Dockerfile.
166170
"""
167171
app_name = app_name or os.path.basename(agent_folder)
168172

@@ -211,6 +215,7 @@ def to_cloud_run(
211215
adk_version=adk_version,
212216
host_option=host_option,
213217
a2a_option=a2a_option,
218+
build_image=build_image,
214219
)
215220
dockerfile_path = os.path.join(temp_folder, 'Dockerfile')
216221
os.makedirs(temp_folder, exist_ok=True)
@@ -474,6 +479,7 @@ def to_gke(
474479
session_service_uri: Optional[str] = None,
475480
artifact_service_uri: Optional[str] = None,
476481
memory_service_uri: Optional[str] = None,
482+
build_image: Optional[str] = BASE_BUILD_IMAGE,
477483
a2a: bool = False,
478484
):
479485
"""Deploys an agent to Google Kubernetes Engine(GKE).
@@ -495,6 +501,7 @@ def to_gke(
495501
session_service_uri: The URI of the session service.
496502
artifact_service_uri: The URI of the artifact service.
497503
memory_service_uri: The URI of the memory service.
504+
build_image: The image to use for building the Dockerfile.
498505
"""
499506
click.secho(
500507
'\n🚀 Starting ADK Agent Deployment to GKE...', fg='cyan', bold=True
@@ -556,6 +563,7 @@ def to_gke(
556563
adk_version=adk_version,
557564
host_option=host_option,
558565
a2a_option='--a2a' if a2a else '',
566+
build_image=build_image,
559567
)
560568
dockerfile_path = os.path.join(temp_folder, 'Dockerfile')
561569
os.makedirs(temp_folder, exist_ok=True)

src/google/adk/cli/cli_tools_click.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,8 @@
4444
case_sensitive=False,
4545
)
4646

47+
BASE_BUILD_IMAGE = "python:3.11-slim"
48+
4749

4850
class HelpfulCommand(click.Command):
4951
"""Command that shows full help on error instead of just the error message.
@@ -968,6 +970,13 @@ def cli_api_server(
968970
help="Optional. Any additional origins to allow for CORS.",
969971
multiple=True,
970972
)
973+
@click.option(
974+
"--build_image",
975+
type=str,
976+
default=BASE_BUILD_IMAGE,
977+
show_default=True,
978+
help="Optional. The docker build version used in Cloud Run deployment. ",
979+
)
971980
# TODO: Add eval_storage_uri option back when evals are supported in Cloud Run.
972981
@adk_services_options()
973982
@deprecated_adk_services_options()
@@ -991,6 +1000,7 @@ def cli_deploy_cloud_run(
9911000
session_db_url: Optional[str] = None, # Deprecated
9921001
artifact_storage_uri: Optional[str] = None, # Deprecated
9931002
a2a: bool = False,
1003+
build_image: Optional[str] = BASE_BUILD_IMAGE,
9941004
):
9951005
"""Deploys an agent to Cloud Run.
9961006
@@ -1029,6 +1039,7 @@ def cli_deploy_cloud_run(
10291039
artifact_service_uri=artifact_service_uri,
10301040
memory_service_uri=memory_service_uri,
10311041
a2a=a2a,
1042+
build_image=build_image,
10321043
)
10331044
except Exception as e:
10341045
click.secho(f"Deploy failed: {e}", fg="red", err=True)
@@ -1281,6 +1292,13 @@ def cli_deploy_agent_engine(
12811292
" version in the dev environment)"
12821293
),
12831294
)
1295+
@click.option(
1296+
"--build_image",
1297+
type=str,
1298+
default=BASE_BUILD_IMAGE,
1299+
show_default=True,
1300+
help="Optional. The docker build version used in GKE deployment. ",
1301+
)
12841302
@adk_services_options()
12851303
@click.argument(
12861304
"agent",
@@ -1304,6 +1322,7 @@ def cli_deploy_gke(
13041322
session_service_uri: Optional[str] = None,
13051323
artifact_service_uri: Optional[str] = None,
13061324
memory_service_uri: Optional[str] = None,
1325+
build_image: Optional[str] = BASE_BUILD_IMAGE,
13071326
):
13081327
"""Deploys an agent to GKE.
13091328
@@ -1330,6 +1349,7 @@ def cli_deploy_gke(
13301349
session_service_uri=session_service_uri,
13311350
artifact_service_uri=artifact_service_uri,
13321351
memory_service_uri=memory_service_uri,
1352+
build_image=build_image,
13331353
)
13341354
except Exception as e:
13351355
click.secho(f"Deploy failed: {e}", fg="red", err=True)

tests/unittests/cli/utils/test_cli_tools_click.py

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -168,11 +168,43 @@ def test_cli_deploy_cloud_run_success(
168168
"proj",
169169
"--region",
170170
"asia-northeast1",
171+
"--build_image",
172+
"my-custom-image",
171173
str(agent_dir),
172174
],
173175
)
174176
assert result.exit_code == 0
175177
assert rec.calls, "cli_deploy.to_cloud_run must be invoked"
178+
called_kwargs = rec.calls[0][1]
179+
assert called_kwargs.get("build_image") == "my-custom-image"
180+
181+
182+
def test_cli_deploy_cloud_run_default_build_image(
183+
tmp_path: Path, monkeypatch: pytest.MonkeyPatch
184+
) -> None:
185+
"""Test that the default build_image is used."""
186+
rec = _Recorder()
187+
monkeypatch.setattr(cli_tools_click.cli_deploy, "to_cloud_run", rec)
188+
189+
agent_dir = tmp_path / "agent2"
190+
agent_dir.mkdir()
191+
runner = CliRunner()
192+
result = runner.invoke(
193+
cli_tools_click.main,
194+
[
195+
"deploy",
196+
"cloud_run",
197+
"--project",
198+
"proj",
199+
"--region",
200+
"asia-northeast1",
201+
str(agent_dir),
202+
],
203+
)
204+
assert result.exit_code == 0
205+
assert rec.calls, "cli_deploy.to_cloud_run must be invoked"
206+
called_kwargs = rec.calls[0][1]
207+
assert called_kwargs.get("build_image") == cli_tools_click.BASE_BUILD_IMAGE
176208

177209

178210
def test_cli_deploy_cloud_run_failure(
@@ -251,6 +283,8 @@ def test_cli_deploy_gke_success(
251283
"us-central1",
252284
"--cluster_name",
253285
"my-cluster",
286+
"--build_image",
287+
"my-gke-image",
254288
str(agent_dir),
255289
],
256290
)
@@ -260,6 +294,37 @@ def test_cli_deploy_gke_success(
260294
assert called_kwargs.get("project") == "test-proj"
261295
assert called_kwargs.get("region") == "us-central1"
262296
assert called_kwargs.get("cluster_name") == "my-cluster"
297+
assert called_kwargs.get("build_image") == "my-gke-image"
298+
299+
300+
def test_cli_deploy_gke_default_build_image(
301+
tmp_path: Path, monkeypatch: pytest.MonkeyPatch
302+
) -> None:
303+
"""Test that the default build_image is used for gke."""
304+
rec = _Recorder()
305+
monkeypatch.setattr(cli_tools_click.cli_deploy, "to_gke", rec)
306+
307+
agent_dir = tmp_path / "agent_gke"
308+
agent_dir.mkdir()
309+
runner = CliRunner()
310+
result = runner.invoke(
311+
cli_tools_click.main,
312+
[
313+
"deploy",
314+
"gke",
315+
"--project",
316+
"test-proj",
317+
"--region",
318+
"us-central1",
319+
"--cluster_name",
320+
"my-cluster",
321+
str(agent_dir),
322+
],
323+
)
324+
assert result.exit_code == 0
325+
assert rec.calls, "cli_deploy.to_gke must be invoked"
326+
called_kwargs = rec.calls[0][1]
327+
assert called_kwargs.get("build_image") == cli_tools_click.BASE_BUILD_IMAGE
263328

264329

265330
# cli eval

0 commit comments

Comments
 (0)