feat: add retry options to cli build command (#81)

An issue was filed for adding retry logic to our push_image command in
the CLI. https://github.com/blue-build/cli/issues/79.

This PR adds:
- **retry flag**
  - `-r`
  - defaults to true 
- **retry_count flag**
  - `--retry_count`
  - defaults to 1

This functionality will be extended to our other services in build
(podman api as well once that is hooked up), but this is the initial
ground work

---------

Co-authored-by: Gerald Pinder <gmpinder@gmail.com>
This commit is contained in:
Hikari 2024-02-23 22:53:50 -06:00 committed by GitHub
parent 681aab4a85
commit 0b4e1003a2
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 32 additions and 1 deletions

View file

@ -67,6 +67,16 @@ pub struct BuildCommand {
#[builder(default)]
push: bool,
/// Allow `bluebuild` to retry pushing images if it fails.
#[arg(short, long, default_value_t = true)]
#[builder(default)]
retry_push: bool,
/// The number of times to retry pushing the image.
#[arg(long, default_value_t = 1)]
#[builder(default)]
retry_count: u8,
/// Allow `bluebuild` to overwrite an existing
/// Containerfile without confirmation.
///
@ -574,7 +584,11 @@ impl BuildCommand {
}
if self.push {
push_images(tags, image_name)?;
let retry = self.retry_push;
let retry_count = if retry { self.retry_count } else { 0 };
// Push images with retries (1s delay between retries)
ops::retry(retry_count, 1000, || push_images(tags, image_name))?;
sign_images(image_name, tags.first().map(String::as_str))?;
}

View file

@ -3,6 +3,7 @@ use std::{io::Write, process::Command};
use anyhow::{anyhow, Result};
use format_serde_error::SerdeError;
use log::{debug, trace};
use std::{thread, time::Duration};
pub fn check_command_exists(command: &str) -> Result<()> {
trace!("check_command_exists({command})");
@ -51,3 +52,19 @@ pub fn serde_yaml_err(contents: &str) -> impl Fn(serde_yaml::Error) -> SerdeErro
)
}
}
pub fn retry<V, F>(mut attempts: u8, delay: u64, f: F) -> anyhow::Result<V>
where
F: Fn() -> anyhow::Result<V>,
{
loop {
match f() {
Ok(v) => return Ok(v),
Err(e) if attempts == 1 => return Err(e),
_ => {
attempts -= 1;
thread::sleep(Duration::from_secs(delay));
}
};
}
}