api/controller/toolchain: Skip empty artifacts
Do not include empty artifacts in the response to avoid publishing
files with no usable information.
BUG=b:202735786
TEST=run_tests
Change-Id: Ib6a0cc3450f9c794534d332e8053ec46c985f82d
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/chromite/+/3229856
Tested-by: Alex Klein <saklein@chromium.org>
Auto-Submit: Alex Klein <saklein@chromium.org>
Reviewed-by: Sergey Frolov <sfrolov@google.com>
diff --git a/api/controller/toolchain.py b/api/controller/toolchain.py
index 1c6c4d1..b2d2c5b 100644
--- a/api/controller/toolchain.py
+++ b/api/controller/toolchain.py
@@ -6,6 +6,7 @@
import collections
import logging
+from pathlib import Path
from chromite.api import controller
from chromite.api import faux
@@ -192,7 +193,7 @@
@validate.exists('output_dir')
@validate.validation_complete
def BundleArtifacts(input_proto, output_proto, _config):
- """Bundle toolchain artifacts.
+ """Bundle valid toolchain artifacts.
The handlers (from _TOOLCHAIN_ARTIFACT_HANDLERS above) are called with:
artifact_name (str): name of the artifact type
@@ -217,20 +218,45 @@
profile_info = _GetProfileInfoDict(input_proto.profile_info)
+ output_path = Path(input_proto.output_dir)
+
for artifact_type in input_proto.artifact_types:
if artifact_type not in _TOOLCHAIN_ARTIFACT_HANDLERS:
logging.error('%s not understood', artifact_type)
return controller.RETURN_CODE_UNRECOVERABLE
+
handler = _TOOLCHAIN_ARTIFACT_HANDLERS[artifact_type]
- if handler and handler.bundle:
- artifacts = handler.bundle(handler.name, chroot, input_proto.sysroot.path,
- input_proto.sysroot.build_target.name,
- input_proto.output_dir, profile_info)
- if artifacts:
- art_info = output_proto.artifacts_info.add()
- art_info.artifact_type = artifact_type
- for artifact in artifacts:
- art_info.artifacts.add().path = artifact
+ if not handler or not handler.bundle:
+ logging.warning('%s does not have a handler with a bundle function.',
+ artifact_type)
+ continue
+
+ artifacts = handler.bundle(handler.name, chroot, input_proto.sysroot.path,
+ input_proto.sysroot.build_target.name,
+ input_proto.output_dir, profile_info)
+ if not artifacts:
+ continue
+
+ # Filter out artifacts that do not exist or are empty.
+ usable_artifacts = []
+ for artifact in artifacts:
+ artifact_path = output_path / artifact
+ if not artifact_path.exists():
+ logging.warning('%s is not in the output directory.', artifact)
+ elif not artifact_path.stat().st_size:
+ logging.warning('%s is empty.', artifact)
+ else:
+ usable_artifacts.append(artifact)
+
+ if not usable_artifacts:
+ logging.warning('No usable artifacts for artifact type %s', artifact_type)
+ continue
+
+ # Add all usable artifacts.
+ art_info = output_proto.artifacts_info.add()
+ art_info.artifact_type = artifact_type
+ for artifact in usable_artifacts:
+ art_info.artifacts.add().path = artifact
def _GetUpdatedFilesResponse(_input_proto, output_proto, _config):