From 94f610ee3b156ccef865c405cd368aa0c7eaba37 Mon Sep 17 00:00:00 2001 From: ohemorange Date: Thu, 11 Jun 2026 12:48:40 -0700 Subject: [PATCH] Get log path from process output to once again print snapcraft logs (#10674) Fixes https://github.com/certbot/certbot/issues/10662 Launchpad is failing, so this should make testing this code pretty easy. There is only one log per target, no matter how many arches, so we can skip the per-arch code. --------- Co-authored-by: Will Greenberg --- tools/snap/build_remote.py | 53 +++++++++++++++++++------------------- 1 file changed, 27 insertions(+), 26 deletions(-) diff --git a/tools/snap/build_remote.py b/tools/snap/build_remote.py index 324caf5f9..5ed9f0e05 100755 --- a/tools/snap/build_remote.py +++ b/tools/snap/build_remote.py @@ -160,7 +160,10 @@ def _build_snap( print(f'Dumping snapcraft remote-build output build for {target}:') print('\n'.join(process_output)) - _dump_failed_build_logs(target, archs, status, workspace) + + assert len(process_output) >= 1 + log_location = _extract_log_location(process_output[-1]) + _dump_failed_build_logs(target, log_location) # Retry the remote build if it has been interrupted (non zero status code) # or if some builds have failed. @@ -171,6 +174,18 @@ def _build_snap( return build_success +def _extract_log_location(line: str) -> str: + result = "" + pattern = r"^Full execution log: '(.+)'$" + match = re.match(pattern, line) + + if match: + result = match.group(1) + else: + print(f'warning: unable to extract log location, expected pattern "{pattern}", got "{line}"') + return result + + def _extract_state(project: str, output: str, status: Dict[str, Dict[str, str]]) -> None: state = status[project] @@ -213,31 +228,18 @@ def _dump_status( time.sleep(10) -def _dump_failed_build_logs( - target: str, archs: Set[str], status: Dict[str, Dict[str, str]], - workspace: str) -> None: - logs_list = glob.glob(join(workspace, f'snapcraft-{target}-*.txt')) - for arch in archs: - result = status[target][arch] +def _dump_failed_build_logs(target:str, build_output_path: str) -> None: + if not build_output_path: + build_output = 'Log location not extracted from output.' + else: + with open(build_output_path) as file_h: + build_output = file_h.read() - if result != 'Succeeded': - failures = True - - # log name is no longer set deterministically as target_arch.txt - # this will still result in a single output though, as we're filtering - # by target above and arch here - build_output_path = [log_name for log_name in logs_list if arch in log_name] - if not build_output_path: - build_output = 'No output has been dumped by snapcraft remote-build.' - else: - with open(build_output_path[0]) as file_h: - build_output = file_h.read() - - print(f'Output for failed build target={target} arch={arch}') - print('-------------------------------------------') - print(build_output) - print('-------------------------------------------') - print() + print(f'Output for failed build target={target}') + print('-------------------------------------------') + print(build_output) + print('-------------------------------------------') + print() def _dump_results(archs: Set[str], status: Dict[str, Dict[str, str]]) -> None: @@ -301,7 +303,6 @@ def main(): workspace = CERTBOT_DIR else: workspace = join(CERTBOT_DIR, target) - _dump_failed_build_logs(target, archs, status, workspace) raise ValueError(f"Timeout out reached ({args.timeout} seconds) during the build!") build_success = True