Skip to content

Retry gcloud SBOM command#3810

Draft
ahmedabu98 wants to merge 2 commits into
GoogleCloudPlatform:mainfrom
ahmedabu98:retry_sbom
Draft

Retry gcloud SBOM command#3810
ahmedabu98 wants to merge 2 commits into
GoogleCloudPlatform:mainfrom
ahmedabu98:retry_sbom

Conversation

@ahmedabu98
Copy link
Copy Markdown
Contributor

No description provided.

@ahmedabu98 ahmedabu98 requested a review from Abacn May 14, 2026 19:46
@gemini-code-assist
Copy link
Copy Markdown

Summary of Changes

Hello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request enhances the reliability of the SBOM generation process within the Maven plugin. By wrapping the gcloud command execution in a retry block with exponential backoff, the system is now better equipped to handle intermittent network or service-related issues, reducing the likelihood of build failures.

Highlights

  • Retry Mechanism Implementation: Introduced a retry loop using Apache Beam's FluentBackoff to handle transient failures during the execution of the gcloud SBOM export command.
  • Improved Build Reliability: Configured the retry logic with an initial backoff of 5 seconds, a maximum backoff of 30 seconds, and up to 5 retries to ensure more resilient SBOM generation.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize the Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counterproductive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for GitHub and other Google products, sign up here.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link
Copy Markdown

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces a manual retry loop using FluentBackoff for the SBOM generation command in TemplatesStageMojo.java. Feedback indicates that this manual retry logic is redundant because the method is already wrapped in a higher-level retry policy. Additionally, a logic bug was identified where the backoff state is advanced twice per iteration, and the new imports would become unnecessary if the manual loop is removed as suggested.

Comment on lines +1784 to 1812
String output = null;

BackOff backOff =
FluentBackoff.DEFAULT
.withInitialBackoff(org.joda.time.Duration.standardSeconds(5))
.withMaxBackoff(org.joda.time.Duration.standardSeconds(30))
.withMaxRetries(5)
.backoff();
Sleeper sleeper = Sleeper.DEFAULT;
Exception lastException;
do {
try {
output =
runCommandCapturesOutput(
new String[] {"gcloud", "artifacts", "sbom", "export", "--uri", imagePathTag},
null);
lastException = null;
break;
} catch (Exception e) {
LOG.error(
"Error generating SBOM. Retrying after {} seconds...",
backOff.nextBackOffMillis() / 1000,
e);
lastException = e;
}
} while (BackOffUtils.next(sleeper, backOff));
if (lastException != null) {
throw new RuntimeException("Error generating SBOM.", lastException);
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

The manual retry loop introduced here is redundant and contains a logic bug.

  1. Redundancy: This run() method is already wrapped in a Failsafe retry policy at line 611 (using sbomRetryPolicy()). Adding a second layer of retries here results in nested retry logic (e.g., 5 retries inside 5 retries), which is likely unintended and significantly increases the total execution time on failure.
  2. Logic Bug: Calling backOff.nextBackOffMillis() inside the log statement (line 1805) and then again in BackOffUtils.next() (line 1809) advances the state of the BackOff object twice per iteration. This causes the loop to skip backoff intervals and terminate after fewer attempts than configured.

It is recommended to remove this manual loop and instead update the parameters in sbomRetryPolicy() (lines 1822-1831) if the retry behavior needs adjustment (e.g., to match the 5s-30s backoff used here).

Suggested change
String output = null;
BackOff backOff =
FluentBackoff.DEFAULT
.withInitialBackoff(org.joda.time.Duration.standardSeconds(5))
.withMaxBackoff(org.joda.time.Duration.standardSeconds(30))
.withMaxRetries(5)
.backoff();
Sleeper sleeper = Sleeper.DEFAULT;
Exception lastException;
do {
try {
output =
runCommandCapturesOutput(
new String[] {"gcloud", "artifacts", "sbom", "export", "--uri", imagePathTag},
null);
lastException = null;
break;
} catch (Exception e) {
LOG.error(
"Error generating SBOM. Retrying after {} seconds...",
backOff.nextBackOffMillis() / 1000,
e);
lastException = e;
}
} while (BackOffUtils.next(sleeper, backOff));
if (lastException != null) {
throw new RuntimeException("Error generating SBOM.", lastException);
}
String output;
try {
output =
runCommandCapturesOutput(
new String[] {"gcloud", "artifacts", "sbom", "export", "--uri", imagePathTag},
null);
} catch (Exception e) {
throw new RuntimeException("Error generating SBOM.", e);
}

Copy link
Copy Markdown
Contributor

@Abacn Abacn May 15, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah it's true that it's already scanned. Checked logs:

[INFO] Generating system SBOM for us.gcr.io/dataflow-templates/yaml-template:2026-05-05-00_RC00...
[INFO] Running: gcloud
[INFO] Generating system SBOM for us.gcr.io/dataflow-templates/yaml-template:2026-05-05-00_RC00...
[INFO] Running: gcloud
[INFO] Generating system SBOM for us.gcr.io/dataflow-templates/yaml-template:2026-05-05-00_RC00...
[INFO] Running: gcloud
[INFO] Generating system SBOM for us.gcr.io/dataflow-templates/yaml-template:2026-05-05-00_RC00...
[INFO] Running: gcloud
[INFO] Generating system SBOM for us.gcr.io/dataflow-templates/yaml-template:2026-05-05-00_RC00...
[INFO] Running: gcloud
[INFO] Generating system SBOM for us.gcr.io/dataflow-templates/yaml-template:2026-05-05-00_RC00...
[INFO] Running: gcloud

Error is

ERROR: (gcloud.artifacts.sbom.export) NOT_FOUND: unable to find discovery occurrence for https://us.gcr.io/dataflow-templates/yaml-template@sha256:1d71b93f588eba08cceaa5ec3057439497bf85bbf7189684b47955beab10251e. Please first scan the artifact.

actually it's due to previously docker build gcb job timed out:

ERROR: (gcloud.builds.submit) build a96c34f7-12ae-4bc0-b149-6cae07ceef5b completed with status "TIMEOUT"

but the docker file was pushed, so pushed container existence check, but likely it's actually incomplete and gcloud artfiacts sbom export command would fail.

Comment on lines +76 to +79
import org.apache.beam.sdk.util.BackOff;
import org.apache.beam.sdk.util.BackOffUtils;
import org.apache.beam.sdk.util.FluentBackoff;
import org.apache.beam.sdk.util.Sleeper;
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

These imports are no longer needed if the manual retry loop in GenerateSBOMRunnable is removed as suggested. Keeping unused imports can lead to confusion and slightly increases the overhead of the class.

@codecov
Copy link
Copy Markdown

codecov Bot commented May 14, 2026

Codecov Report

❌ Patch coverage is 0% with 18 lines in your changes missing coverage. Please review.
✅ Project coverage is 53.71%. Comparing base (a292e17) to head (c947300).
⚠️ Report is 1 commits behind head on main.

Files with missing lines Patch % Lines
...loud/teleport/plugin/maven/TemplatesStageMojo.java 0.00% 18 Missing ⚠️

❌ Your patch check has failed because the patch coverage (0.00%) is below the target coverage (80.00%). You can increase the patch coverage or adjust the target coverage.

Additional details and impacted files
@@             Coverage Diff              @@
##               main    #3810      +/-   ##
============================================
- Coverage     53.73%   53.71%   -0.02%     
  Complexity     6741     6741              
============================================
  Files          1087     1087              
  Lines         66804    66807       +3     
  Branches       7479     7480       +1     
============================================
- Hits          35897    35888       -9     
- Misses        28479    28490      +11     
- Partials       2428     2429       +1     
Components Coverage Δ
spanner-templates 72.83% <ø> (-0.01%) ⬇️
spanner-import-export 68.64% <ø> (-0.03%) ⬇️
spanner-live-forward-migration 80.94% <ø> (ø)
spanner-live-reverse-replication 77.09% <ø> (ø)
spanner-bulk-migration 91.11% <ø> (ø)
gcs-spanner-dv 85.76% <ø> (ø)
Files with missing lines Coverage Δ
...loud/teleport/plugin/maven/TemplatesStageMojo.java 16.96% <0.00%> (-0.31%) ⬇️

... and 6 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@ahmedabu98 ahmedabu98 marked this pull request as draft May 14, 2026 22:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants