Build a Docker image from composed content
(
&self,
composed: &ComposedDockerfile,
git_user_name: &str,
git_user_email: &str,
agent_version: Option<&str>,
options: &BuildOptions<'_>,
)
| 418 | |
| 419 | /// Build a Docker image from composed content |
| 420 | async fn build_docker_image( |
| 421 | &self, |
| 422 | composed: &ComposedDockerfile, |
| 423 | git_user_name: &str, |
| 424 | git_user_email: &str, |
| 425 | agent_version: Option<&str>, |
| 426 | options: &BuildOptions<'_>, |
| 427 | ) -> Result<()> { |
| 428 | // Create tar archive from the composed content |
| 429 | let tar_archive = self |
| 430 | .create_tar_archive(composed, options.build_root) |
| 431 | .context("Failed to create tar archive for Docker build")?; |
| 432 | |
| 433 | // Prepare build options |
| 434 | let mut build_args = std::collections::HashMap::new(); |
| 435 | |
| 436 | // Add build arguments if they exist in the Dockerfile |
| 437 | if composed.build_args.contains("GIT_USER_NAME") { |
| 438 | build_args.insert("GIT_USER_NAME".to_string(), git_user_name.to_string()); |
| 439 | } |
| 440 | |
| 441 | if composed.build_args.contains("GIT_USER_EMAIL") { |
| 442 | build_args.insert("GIT_USER_EMAIL".to_string(), git_user_email.to_string()); |
| 443 | } |
| 444 | |
| 445 | // Add agent version if provided and if ARG exists in Dockerfile |
| 446 | if let Some(version) = agent_version |
| 447 | && composed.build_args.contains("TSK_AGENT_VERSION") |
| 448 | { |
| 449 | build_args.insert("TSK_AGENT_VERSION".to_string(), version.to_string()); |
| 450 | } |
| 451 | |
| 452 | // Pass host UID/GID so the container's "agent" user matches the host user. |
| 453 | // On macOS, Docker Desktop transparently maps file permissions between the |
| 454 | // host and the Linux VM, so we use the Dockerfile defaults (1000:1000) to |
| 455 | // avoid GID collisions and subuid issues with non-Linux UID/GID ranges. |
| 456 | if cfg!(target_os = "linux") { |
| 457 | if composed.build_args.contains("HOST_UID") { |
| 458 | // SAFETY: getuid/getgid are simple syscalls with no preconditions |
| 459 | build_args.insert( |
| 460 | "HOST_UID".to_string(), |
| 461 | unsafe { libc::getuid() }.to_string(), |
| 462 | ); |
| 463 | } |
| 464 | if composed.build_args.contains("HOST_GID") { |
| 465 | build_args.insert( |
| 466 | "HOST_GID".to_string(), |
| 467 | unsafe { libc::getgid() }.to_string(), |
| 468 | ); |
| 469 | } |
| 470 | } |
| 471 | |
| 472 | if self.ctx.tsk_config().container_engine == ContainerEngine::Podman { |
| 473 | if std::env::var("TSK_CONTAINER").is_ok() { |
| 474 | // Inside a TSK container, forward proxy env vars so Podman builds |
| 475 | // route through the Squid proxy. |
| 476 | for var in super::PROXY_ENV_VARS { |
| 477 | if let Ok(val) = std::env::var(var) { |
no test coverage detected