Skip to content

Commit

Permalink
bubble async up to avoid nested tokio runtime panics
Browse files Browse the repository at this point in the history
Signed-off-by: Robert Detjens <[email protected]>
  • Loading branch information
detjensrobert committed Feb 2, 2025
1 parent fda8220 commit 06f1dba
Show file tree
Hide file tree
Showing 4 changed files with 37 additions and 31 deletions.
3 changes: 1 addition & 2 deletions src/builder/docker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@ pub struct ContainerInfo {
id: String,
}

#[tokio::main(flavor = "current_thread")] // make this a sync function
pub async fn build_image(context: &Path, options: &BuildObject, tag: &str) -> Result<String> {
trace!("building image in directory {context:?} to tag {tag:?}");
let client = docker().await?;
Expand Down Expand Up @@ -84,7 +83,7 @@ pub async fn build_image(context: &Path, options: &BuildObject, tag: &str) -> Re
Ok(tag.to_string())
}

#[tokio::main(flavor = "current_thread")] // make this a sync function
// #[tokio::main(flavor = "current_thread")] // make this a sync function
pub async fn push_image(image_tag: &str, creds: &UserPass) -> Result<String> {
info!("pushing image {image_tag:?} to registry");
let client = docker().await?;
Expand Down
58 changes: 32 additions & 26 deletions src/builder/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,19 +47,25 @@ pub enum TagWithSource {
}

/// Build all enabled challenges for the given profile. Returns tags built
pub fn build_challenges(
pub async fn build_challenges(
profile_name: &str,
push: bool,
extract_artifacts: bool,
) -> Result<Vec<(&ChallengeConfig, BuildResult)>> {
enabled_challenges(profile_name)?
.into_iter()
.map(|chal| build_challenge(profile_name, chal, push, extract_artifacts).map(|r| (chal, r)))
.collect::<Result<_>>()
try_join_all(
enabled_challenges(profile_name)?
.into_iter()
.map(|chal| async move {
build_challenge(profile_name, chal, push, extract_artifacts)
.await
.map(|r| (chal, r))
}),
)
.await
}

/// Build all images from given challenge, optionally pushing image or extracting artifacts
fn build_challenge(
async fn build_challenge(
profile_name: &str,
chal: &ChallengeConfig,
push: bool,
Expand All @@ -73,27 +79,28 @@ fn build_challenge(
assets: vec![],
};

built.tags = chal
.pods
.iter()
.map(|p| match &p.image_source {
built.tags = try_join_all(chal.pods.iter().map(|p| async {
match &p.image_source {
Image(tag) => Ok(TagWithSource::Upstream(tag.to_string())),
// build any pods that need building
Build(build) => {
let tag = chal.container_tag_for_pod(profile_name, &p.name)?;

let res = docker::build_image(&chal.directory, build, &tag).with_context(|| {
format!(
"error building image {} for chal {}",
p.name,
chal.directory.to_string_lossy()
)
});
let res = docker::build_image(&chal.directory, build, &tag)
.await
.with_context(|| {
format!(
"error building image {} for chal {}",
p.name,
chal.directory.to_string_lossy()
)
});
// map result tag string into enum
res.map(TagWithSource::Built)
}
})
.collect::<Result<_>>()?;
}
}))
.await?;

if push {
// only need to push tags we actually built
Expand All @@ -112,13 +119,12 @@ fn build_challenge(
chal.directory
);

tags_to_push
.iter()
.map(|tag| {
docker::push_image(tag, &config.registry.build)
.with_context(|| format!("error pushing image {tag}"))
})
.collect::<Result<Vec<_>>>()?;
try_join_all(tags_to_push.iter().map(|tag| async move {
docker::push_image(tag, &config.registry.build)
.await
.with_context(|| format!("error pushing image {tag}"))
}))
.await?;
}

if extract_artifacts {
Expand Down
5 changes: 3 additions & 2 deletions src/commands/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,11 @@ use std::process::exit;
use crate::builder::build_challenges;
use crate::configparser::{get_config, get_profile_config};

pub fn run(profile_name: &str, push: &bool, extract: &bool) {
#[tokio::main(flavor = "current_thread")] // make this a sync function
pub async fn run(profile_name: &str, push: &bool, extract: &bool) {
info!("building images...");

let results = match build_challenges(profile_name, *push, *extract) {
let results = match build_challenges(profile_name, *push, *extract).await {
Ok(results) => results,
Err(e) => {
error!("{e:?}");
Expand Down
2 changes: 1 addition & 1 deletion src/commands/deploy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ pub async fn run(profile_name: &str, no_build: &bool, _dry_run: &bool) {
}

info!("building challenges...");
let build_results = match build_challenges(profile_name, true, true) {
let build_results = match build_challenges(profile_name, true, true).await {
Ok(result) => result,
Err(e) => {
error!("{e:?}");
Expand Down

0 comments on commit 06f1dba

Please sign in to comment.