From 8f57b08f2c57082c13fb80b900ac3d64bfd3bf08 Mon Sep 17 00:00:00 2001 From: Alexey Rybak <50731695+reluctantfuturist@users.noreply.github.com> Date: Thu, 17 Apr 2025 01:20:43 -0700 Subject: [PATCH] fix(build): always pass path when no template/config provided (#1982) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit # What does this PR do? Fixes a crash that occurred when building a stack as a container image via the interactive wizard without supplying --template or --config. - Root cause: template_or_config was None; only the container path relies on that parameter, which later reaches subprocess.run() and triggers `TypeError: expected str, bytes or os.PathLike object, not NoneType.` - Change: in `_run_stack_build_command_from_build_config` we now fall back to the freshly‑written build‑spec file whenever both optional sources are missing. Also adds a spy‑based unit test that asserts a valid string path is passed to build_image() for container builds. ### Closes #1976 ## Test Plan - New unit test: test_build_path.py. Monkey‑patches build_image, captures the fourth argument, and verifies it is a real path - Manual smoke test: ``` llama stack build --image-type container # answer wizard prompts ``` Build proceeds into Docker without raising the previous TypeError. ## Future Work Harmonise `build_image` arguments so every image type receives the same inputs, eliminating this asymmetric special‑case. --- llama_stack/cli/stack/_build.py | 2 +- tests/unit/distribution/test_build_path.py | 38 ++++++++++++++++++++++ 2 files changed, 39 insertions(+), 1 deletion(-) create mode 100644 tests/unit/distribution/test_build_path.py diff --git a/llama_stack/cli/stack/_build.py b/llama_stack/cli/stack/_build.py index f69958c41..760ba2e5a 100644 --- a/llama_stack/cli/stack/_build.py +++ b/llama_stack/cli/stack/_build.py @@ -354,7 +354,7 @@ def _run_stack_build_command_from_build_config( build_config, build_file_path, image_name, - template_or_config=template_name or config_path, + template_or_config=template_name or config_path or str(build_file_path), ) if return_code != 0: raise RuntimeError(f"Failed to build image {image_name}") diff --git a/tests/unit/distribution/test_build_path.py b/tests/unit/distribution/test_build_path.py new file mode 100644 index 000000000..a913bd88b --- /dev/null +++ b/tests/unit/distribution/test_build_path.py @@ -0,0 +1,38 @@ +# Copyright (c) Meta Platforms, Inc. and affiliates. +# All rights reserved. +# +# This source code is licensed under the terms described in the LICENSE file in +# the root directory of this source tree. + +from pathlib import Path + +from llama_stack.cli.stack._build import ( + _run_stack_build_command_from_build_config, +) +from llama_stack.distribution.datatypes import BuildConfig, DistributionSpec +from llama_stack.distribution.utils.image_types import LlamaStackImageType + + +def test_container_build_passes_path(monkeypatch, tmp_path): + called_with = {} + + def spy_build_image(cfg, build_file_path, image_name, template_or_config): + called_with["path"] = template_or_config + return 0 + + monkeypatch.setattr( + "llama_stack.cli.stack._build.build_image", + spy_build_image, + raising=True, + ) + + cfg = BuildConfig( + image_type=LlamaStackImageType.CONTAINER.value, + distribution_spec=DistributionSpec(providers={}, description=""), + ) + + _run_stack_build_command_from_build_config(cfg, image_name="dummy") + + assert "path" in called_with + assert isinstance(called_with["path"], str) + assert Path(called_with["path"]).exists()