1
0
Fork 0
mirror of https://github.com/imjasonh/krust synced 2026-07-08 06:45:32 +00:00

Merge pull request #52 from imjasonh/conc

build concurrently
This commit is contained in:
Jason Hall 2025-10-15 16:21:57 -04:00 committed by GitHub
commit d9bef924aa
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -91,91 +91,120 @@ async fn main() -> Result<()> {
} }
}; };
// Build for each platform // Build for each platform concurrently
let mut manifest_descriptors = Vec::new(); let mut tasks = Vec::new();
for platform_str in &platforms { for platform_str in platforms.clone() {
info!("Building for platform: {}", platform_str); let project_path = project_path.clone();
let base_image = base_image.clone();
let target_repo = target_repo.clone();
let cargo_args = cargo_args.clone();
let no_push_flag = no_push;
// Build the Rust binary for this platform let task = tokio::spawn(async move {
let target = get_rust_target_triple(platform_str)?; info!("Building for platform: {}", platform_str);
let builder =
RustBuilder::new(&project_path, &target).with_cargo_args(cargo_args.clone());
let build_result = builder.build()?; // Build the Rust binary for this platform
let target = get_rust_target_triple(&platform_str)?;
let builder =
RustBuilder::new(&project_path, &target).with_cargo_args(cargo_args);
// Build container image for this platform let build_result = builder.build()?;
let image_builder = ImageBuilder::new(
build_result.binary_path,
base_image.clone(),
platform_str.clone(),
);
// Always use layered approach - registry layer will handle cross-registry blob copying // Build container image for this platform
let base_auth = resolve_auth(&base_image)?; let image_builder = ImageBuilder::new(
let (config_data, layer_data, manifest) = image_builder build_result.binary_path,
.build(&mut registry_client, &base_auth) base_image.clone(),
.await?; platform_str.clone(),
);
// Push platform-specific image if not --no-push // Create a registry client for this task
if !no_push { let mut registry_client = RegistryClient::new()?;
info!("Pushing image for platform: {}", platform_str);
// Get auth for the target registry // Always use layered approach - registry layer will handle cross-registry blob copying
let push_auth = resolve_auth(&target_repo)?; let base_auth = resolve_auth(&base_image)?;
let (config_data, layer_data, manifest) = image_builder
// Get the media type of the application layer (last layer in manifest) .build(&mut registry_client, &base_auth)
let app_layer_media_type = manifest
.layers
.last()
.map(|l| l.media_type.clone())
.unwrap_or_else(|| {
"application/vnd.docker.image.rootfs.diff.tar.gzip".to_string()
});
// Push layered image by digest only (no tag)
// This will be referenced by digest in the final manifest list
let (digest_ref, manifest_size) = registry_client
.push_layered_image(
&target_repo,
config_data,
layer_data,
app_layer_media_type,
&manifest,
&push_auth,
&base_image,
&base_auth,
)
.await?; .await?;
// Parse platform string // Push platform-specific image if not --no-push
let parts: Vec<&str> = platform_str.split('/').collect(); let manifest_descriptor = if !no_push_flag {
let (os, arch) = if parts.len() >= 2 { info!("Pushing image for platform: {}", platform_str);
(parts[0].to_string(), parts[1].to_string())
// Get auth for the target registry
let push_auth = resolve_auth(&target_repo)?;
// Get the media type of the application layer (last layer in manifest)
let app_layer_media_type = manifest
.layers
.last()
.map(|l| l.media_type.clone())
.unwrap_or_else(|| {
"application/vnd.docker.image.rootfs.diff.tar.gzip".to_string()
});
// Push layered image by digest only (no tag)
// This will be referenced by digest in the final manifest list
let (digest_ref, manifest_size) = registry_client
.push_layered_image(
&target_repo,
config_data,
layer_data,
app_layer_media_type,
&manifest,
&push_auth,
&base_image,
&base_auth,
)
.await?;
// Parse platform string
let parts: Vec<&str> = platform_str.split('/').collect();
let (os, arch) = if parts.len() >= 2 {
(parts[0].to_string(), parts[1].to_string())
} else {
return Err(anyhow::anyhow!(
"Invalid platform format: {}",
platform_str
));
};
// Extract just the digest from the full reference
let digest = digest_ref.split('@').next_back().unwrap_or("").to_string();
info!("Pushed platform image to: {}", digest_ref);
// Return manifest descriptor
info!(
"Adding manifest to list - platform: {}/{}, digest: {}, size: {}",
os, arch, digest, manifest_size
);
Some(ManifestDescriptor {
media_type: "application/vnd.oci.image.manifest.v1+json".to_string(),
size: manifest_size as i64,
digest,
platform: Platform {
architecture: arch,
os,
variant: None,
},
})
} else { } else {
return Err(anyhow::anyhow!("Invalid platform format: {}", platform_str)); None
}; };
// Extract just the digest from the full reference Ok::<_, anyhow::Error>(manifest_descriptor)
let digest = digest_ref.split('@').next_back().unwrap_or("").to_string(); });
info!("Pushed platform image to: {}", digest_ref); tasks.push(task);
}
// Add to manifest list // Wait for all builds to complete
info!( let mut manifest_descriptors = Vec::new();
"Adding manifest to list - platform: {}/{}, digest: {}, size: {}", for task in tasks {
os, arch, digest, manifest_size let result = task.await.context("Build task panicked")??;
); if let Some(descriptor) = result {
manifest_descriptors.push(ManifestDescriptor { manifest_descriptors.push(descriptor);
media_type: "application/vnd.oci.image.manifest.v1+json".to_string(),
size: manifest_size as i64,
digest,
platform: Platform {
architecture: arch,
os,
variant: None,
},
});
} }
} }