Skip to content

Commit fd75e84

Browse files
bentveljJared Bentvelsen
and
Jared Bentvelsen
authored
Warn for missing BuildArchitecture during Layer build (#6355)
* wip * Add check for BuildArchitecture in LayerVersion constructor * Add check in Compatible architectures * Add test for BuildArch not in CompatibleArch * formatting fixes * Fix string too long * Remove unnecessary changes * Format fix --------- Co-authored-by: Jared Bentvelsen <bentvels@amazon.com>
1 parent 5c5bf2d commit fd75e84

File tree

4 files changed

+74
-2
lines changed

4 files changed

+74
-2
lines changed

samcli/lib/providers/provider.py

+14-1
Original file line numberDiff line numberDiff line change
@@ -242,11 +242,24 @@ def __init__(
242242
self._metadata = metadata
243243
self._build_method = cast(Optional[str], metadata.get("BuildMethod", None))
244244
self._compatible_runtimes = compatible_runtimes
245+
self._custom_layer_id = metadata.get(SAM_RESOURCE_ID_KEY)
246+
247+
if "BuildArchitecture" not in metadata:
248+
LOG.warning(
249+
f"WARNING: No BuildArchitecture specifed in Layer `{self._custom_layer_id}`"
250+
+ " Metadata. Defaulting to x86_64."
251+
)
245252

246253
self._build_architecture = cast(str, metadata.get("BuildArchitecture", X86_64))
247254
self._compatible_architectures = compatible_architectures
255+
256+
if self._compatible_architectures and self._build_architecture not in self._compatible_architectures:
257+
LOG.warning(
258+
f"WARNING: Layer `{self._custom_layer_id}` has BuildArchitecture `{self._build_architecture}`,"
259+
+ " which is not listed in CompatibleArchitectures."
260+
)
261+
248262
self._skip_build = bool(metadata.get(SAM_METADATA_SKIP_BUILD_KEY, False))
249-
self._custom_layer_id = metadata.get(SAM_RESOURCE_ID_KEY)
250263

251264
@staticmethod
252265
def _compute_layer_version(is_defined_within_template: bool, arn: str) -> Optional[int]:

tests/integration/buildcmd/test_build_cmd.py

+40
Original file line numberDiff line numberDiff line change
@@ -1494,6 +1494,33 @@ def test_build_layer_with_makefile_no_compatible_runtimes(self):
14941494
"random",
14951495
)
14961496

1497+
@parameterized.expand(
1498+
[("makefile", False), ("makefile", "use_container"), ("python3.9", False), ("python3.9", "use_container")]
1499+
)
1500+
def test_build_layer_with_architecture_not_compatible(self, build_method, use_container):
1501+
# The BuildArchitecture is not one of the listed CompatibleArchitectures
1502+
1503+
layer_identifier = "LayerWithNoCompatibleArchitectures"
1504+
1505+
overrides = {
1506+
"LayerBuildMethod": build_method,
1507+
"LayerMakeContentUri": "PyLayerMake",
1508+
"LayerBuildArchitecture": "x86_64",
1509+
"LayerCompatibleArchitecture": "arm64",
1510+
}
1511+
cmdlist = self.get_command_list(
1512+
use_container=use_container, parameter_overrides=overrides, function_identifier=layer_identifier
1513+
)
1514+
1515+
command_result = run_command(cmdlist, cwd=self.working_dir)
1516+
# Capture warning
1517+
self.assertIn(
1518+
f"Layer `{layer_identifier}` has BuildArchitecture `x86_64`, which is not listed in CompatibleArchitectures.",
1519+
str(command_result.stderr),
1520+
)
1521+
# Build should still succeed
1522+
self.assertEqual(command_result.process.returncode, 0)
1523+
14971524
@parameterized.expand([("python3.7", False, "LayerTwo"), ("python3.7", "use_container", "LayerTwo")])
14981525
def test_build_fails_with_missing_metadata(self, runtime, use_container, layer_identifier):
14991526
if use_container and (SKIP_DOCKER_TESTS or SKIP_DOCKER_BUILD):
@@ -1508,6 +1535,19 @@ def test_build_fails_with_missing_metadata(self, runtime, use_container, layer_i
15081535
self.assertEqual(command_result.process.returncode, 1)
15091536
self.assertFalse(self.default_build_dir.joinpath(layer_identifier).exists())
15101537

1538+
@parameterized.expand([("python3.7", False, "LayerOne"), ("python3.7", "use_container", "LayerOne")])
1539+
def test_build_with_missing_buildarchitecture(self, runtime, use_container, layer_identifier):
1540+
if use_container and (SKIP_DOCKER_TESTS or SKIP_DOCKER_BUILD):
1541+
self.skipTest(SKIP_DOCKER_MESSAGE)
1542+
1543+
overrides = {"LayerBuildMethod": runtime, "LayerContentUri": "PyLayer"}
1544+
cmdlist = self.get_command_list(
1545+
use_container=use_container, parameter_overrides=overrides, function_identifier=layer_identifier
1546+
)
1547+
command_result = run_command(cmdlist, cwd=self.working_dir)
1548+
self.assertEqual(command_result.process.returncode, 0)
1549+
self.assertIn("No BuildArchitecture specifed", str(command_result.stderr))
1550+
15111551
@parameterized.expand([("python3.7", False), ("python3.7", "use_container")])
15121552
def test_build_function_and_layer(self, runtime, use_container):
15131553
if use_container and (SKIP_DOCKER_TESTS or SKIP_DOCKER_BUILD):

tests/integration/testdata/buildcmd/PyLayerMake/Makefile

+4-1
Original file line numberDiff line numberDiff line change
@@ -7,4 +7,7 @@ build-LayerWithMakefileNoCompatibleRuntimes:
77
mkdir -p "$(ARTIFACTS_DIR)/random"
88
cp *.py "$(ARTIFACTS_DIR)/random"
99
cp *.txt "$(ARTIFACTS_DIR)/random"
10-
10+
build-LayerWithNoCompatibleArchitectures:
11+
mkdir -p "$(ARTIFACTS_DIR)/random"
12+
cp *.py "$(ARTIFACTS_DIR)/random"
13+
cp *.txt "$(ARTIFACTS_DIR)/random"

tests/integration/testdata/buildcmd/layers-functions-template.yaml

+16
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,11 @@ Parameters:
1414
Type: String
1515
LayerBuildMethod:
1616
Type: String
17+
LayerBuildArchitecture:
18+
Default: x86_64
19+
Type: String
20+
LayerCompatibleArchitecture:
21+
Type: String
1722

1823
Resources:
1924

@@ -72,3 +77,14 @@ Resources:
7277
ContentUri: !Ref LayerMakeContentUri
7378
Metadata:
7479
BuildMethod: !Ref LayerBuildMethod
80+
81+
LayerWithNoCompatibleArchitectures:
82+
Type: AWS::Serverless::LayerVersion
83+
Properties:
84+
Description: Layer four
85+
ContentUri: !Ref LayerMakeContentUri
86+
CompatibleArchitectures:
87+
- !Ref LayerCompatibleArchitecture
88+
Metadata:
89+
BuildMethod: !Ref LayerBuildMethod
90+
BuildArchitecture: !Ref LayerBuildArchitecture

0 commit comments

Comments
 (0)