Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: Remove image for docker inspect after running image to get version #328

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 26 additions & 12 deletions process/drivers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -271,6 +271,12 @@ fn get_version_run_image(oci_ref: &Reference) -> Result<u64> {
);
progress.enable_steady_tick(Duration::from_millis(100));

let should_remove = if matches!(Driver::get_run_driver(), RunDriverType::Docker) {
!Driver::list_images()?.contains(oci_ref)
} else {
false
};

let output = Driver::run_output(
&RunOpts::builder()
.image(oci_ref.to_string())
Expand All @@ -284,6 +290,10 @@ fn get_version_run_image(oci_ref: &Reference) -> Result<u64> {
.build(),
)?;

if should_remove {
Driver::remove_image(oci_ref)?;
}

progress.finish_and_clear();
Logger::multi_progress().remove(&progress);

Expand Down Expand Up @@ -396,6 +406,22 @@ impl RunDriver for Driver {
fn run_output(opts: &RunOpts) -> Result<Output> {
impl_run_driver!(run_output(opts))
}

fn create_container(image: &Reference) -> Result<types::ContainerId> {
impl_run_driver!(create_container(image))
}

fn remove_container(container_id: &types::ContainerId) -> Result<()> {
impl_run_driver!(remove_container(container_id))
}

fn remove_image(image: &Reference) -> Result<()> {
impl_run_driver!(remove_image(image))
}

fn list_images() -> Result<Vec<Reference>> {
impl_run_driver!(list_images())
}
}

macro_rules! impl_ci_driver {
Expand Down Expand Up @@ -447,18 +473,6 @@ impl CiDriver for Driver {

#[cfg(feature = "rechunk")]
impl ContainerMountDriver for Driver {
fn create_container(image: &Reference) -> Result<types::ContainerId> {
PodmanDriver::create_container(image)
}

fn remove_container(container_id: &types::ContainerId) -> Result<()> {
PodmanDriver::remove_container(container_id)
}

fn remove_image(image: &Reference) -> Result<()> {
PodmanDriver::remove_image(image)
}

fn mount_container(container_id: &types::ContainerId) -> Result<types::MountId> {
PodmanDriver::mount_container(container_id)
}
Expand Down
231 changes: 175 additions & 56 deletions process/drivers/docker_driver.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use std::{
};

use blue_build_utils::{
constants::{BB_BUILDKIT_CACHE_GHA, CONTAINER_FILE, DOCKER_HOST, GITHUB_ACTIONS},
constants::{BB_BUILDKIT_CACHE_GHA, DOCKER_HOST, GITHUB_ACTIONS},
credentials::Credentials,
string_vec,
};
Expand All @@ -16,6 +16,7 @@ use colored::Colorize;
use comlexr::cmd;
use log::{debug, info, trace, warn};
use miette::{bail, miette, IntoDiagnostic, Result};
use oci_distribution::Reference;
use once_cell::sync::Lazy;
use semver::Version;
use serde::Deserialize;
Expand All @@ -30,8 +31,7 @@ use crate::{
RunOptsVolume, TagOpts,
},
traits::{BuildDriver, DriverVersion, InspectDriver, RunDriver},
types::ImageMetadata,
types::Platform,
types::{ContainerId, ImageMetadata, Platform},
},
logging::CommandLogging,
signal_handler::{add_cid, remove_cid, ContainerRuntime, ContainerSignalId},
Expand Down Expand Up @@ -66,9 +66,13 @@ impl DockerDriver {
}

trace!("docker buildx ls --format={}", "{{.Name}}");
let ls_out = cmd!("docker", "buildx", "ls", "--format={{.Name}}")
.output()
.into_diagnostic()?;
let ls_out = {
let c = cmd!("docker", "buildx", "ls", "--format={{.Name}}");
trace!("{c:?}");
c
}
.output()
.into_diagnostic()?;

if !ls_out.status.success() {
bail!("{}", String::from_utf8_lossy(&ls_out.stderr));
Expand All @@ -79,15 +83,18 @@ impl DockerDriver {
trace!("{ls_out}");

if !ls_out.lines().any(|line| line == "bluebuild") {
trace!("docker buildx create --bootstrap --driver=docker-container --name=bluebuild");
let create_out = cmd!(
"docker",
"buildx",
"create",
"--bootstrap",
"--driver=docker-container",
"--name=bluebuild",
)
let create_out = {
let c = cmd!(
"docker",
"buildx",
"create",
"--bootstrap",
"--driver=docker-container",
"--name=bluebuild",
);
trace!("{c:?}");
c
}
.output()
.into_diagnostic()?;

Expand All @@ -108,9 +115,13 @@ impl DriverVersion for DockerDriver {
const VERSION_REQ: &'static str = ">=23";

fn version() -> Result<Version> {
let output = cmd!("docker", "version", "-f", "json")
.output()
.into_diagnostic()?;
let output = {
let c = cmd!("docker", "version", "-f", "json");
trace!("{c:?}");
c
}
.output()
.into_diagnostic()?;

let version_json: DockerVersionJson =
serde_json::from_slice(&output.stdout).into_diagnostic()?;
Expand All @@ -127,20 +138,23 @@ impl BuildDriver for DockerDriver {
warn!("Squash is deprecated for docker so this build will not squash");
}

trace!("docker build -t {} -f {CONTAINER_FILE} .", opts.image);
let status = cmd!(
"docker",
"build",
if !matches!(opts.platform, Platform::Native) => [
"--platform",
opts.platform.to_string(),
],
"-t",
&*opts.image,
"-f",
&*opts.containerfile,
".",
)
let status = {
let c = cmd!(
"docker",
"build",
if !matches!(opts.platform, Platform::Native) => [
"--platform",
opts.platform.to_string(),
],
"-t",
&*opts.image,
"-f",
&*opts.containerfile,
".",
);
trace!("{c:?}");
c
}
.status()
.into_diagnostic()?;

Expand All @@ -157,10 +171,13 @@ impl BuildDriver for DockerDriver {

let dest_image_str = opts.dest_image.to_string();

trace!("docker tag {} {}", opts.src_image, opts.dest_image);
let status = cmd!("docker", "tag", opts.src_image.to_string(), &dest_image_str)
.status()
.into_diagnostic()?;
let status = {
let c = cmd!("docker", "tag", opts.src_image.to_string(), &dest_image_str);
trace!("{c:?}");
c
}
.status()
.into_diagnostic()?;

if status.success() {
info!("Successfully tagged {}!", dest_image_str.bold().green());
Expand All @@ -175,10 +192,13 @@ impl BuildDriver for DockerDriver {

let image_str = opts.image.to_string();

trace!("docker push {}", opts.image);
let status = cmd!("docker", "push", &image_str)
.status()
.into_diagnostic()?;
let status = {
let c = cmd!("docker", "push", &image_str);
trace!("{c:?}");
c
}
.status()
.into_diagnostic()?;

if status.success() {
info!("Successfully pushed {}!", image_str.bold().green());
Expand Down Expand Up @@ -241,14 +261,18 @@ impl BuildDriver for DockerDriver {
let (system, buildx) = std::thread::scope(
|scope| -> std::thread::Result<(Result<ExitStatus>, Result<ExitStatus>)> {
let system = scope.spawn(|| {
cmd!(
"docker",
"system",
"prune",
"--force",
if opts.all => "--all",
if opts.volumes => "--volumes",
)
{
let c = cmd!(
"docker",
"system",
"prune",
"--force",
if opts.all => "--all",
if opts.volumes => "--volumes",
);
trace!("{c:?}");
c
}
.message_status("docker system prune", "Pruning Docker System")
.into_diagnostic()
});
Expand All @@ -260,14 +284,18 @@ impl BuildDriver for DockerDriver {
Self::setup()?;
}

cmd!(
"docker",
"buildx",
"prune",
"--force",
if run_setup => "--builder=bluebuild",
if opts.all => "--all",
)
{
let c = cmd!(
"docker",
"buildx",
"prune",
"--force",
if run_setup => "--builder=bluebuild",
if opts.all => "--all",
);
trace!("{c:?}");
c
}
.message_status("docker buildx prune", "Pruning Docker Buildx")
.into_diagnostic()
});
Expand Down Expand Up @@ -465,6 +493,97 @@ impl RunDriver for DockerDriver {

Ok(output)
}

fn create_container(image: &oci_distribution::Reference) -> Result<super::types::ContainerId> {
trace!("DockerDriver::create_container({image})");

let output = {
let c = cmd!("docker", "create", image.to_string(), "bash",);
trace!("{c:?}");
c
}
.output()
.into_diagnostic()?;

if !output.status.success() {
bail!("Failed to create container from image {image}");
}

Ok(ContainerId(
String::from_utf8(output.stdout.trim_ascii().to_vec()).into_diagnostic()?,
))
}

fn remove_container(container_id: &super::types::ContainerId) -> Result<()> {
trace!("DockerDriver::remove_container({container_id})");

let output = {
let c = cmd!("docker", "rm", container_id);
trace!("{c:?}");
c
}
.output()
.into_diagnostic()?;

if !output.status.success() {
bail!("Failed to remove container {container_id}");
}

Ok(())
}

fn remove_image(image: &oci_distribution::Reference) -> Result<()> {
trace!("DockerDriver::remove_image({image})");

let output = {
let c = cmd!("docker", "rmi", image.to_string());
trace!("{c:?}");
c
}
.output()
.into_diagnostic()?;

if !output.status.success() {
bail!("Failed to remove the image {image}");
}

Ok(())
}

fn list_images() -> Result<Vec<Reference>> {
#[derive(Deserialize)]
#[serde(rename_all = "PascalCase")]
struct Image {
repository: String,
tag: String,
}

let output = {
let c = cmd!("docker", "images", "--format", "json");
trace!("{c:?}");
c
}
.output()
.into_diagnostic()?;

if !output.status.success() {
bail!("Failed to list images");
}

let images: Vec<Image> = String::from_utf8_lossy(&output.stdout)
.lines()
.map(|line| serde_json::from_str::<Image>(line).into_diagnostic())
.collect::<Result<_>>()?;

images
.into_iter()
.map(|image| {
format!("{}:{}", image.repository, image.tag)
.parse::<Reference>()
.into_diagnostic()
})
.collect()
}
}

fn docker_run(opts: &RunOpts, cid_file: &Path) -> Command {
Expand Down
Loading
Loading