Skip to content

Commit

Permalink
feat: Use buildkit api for building
Browse files Browse the repository at this point in the history
  • Loading branch information
gmpinder committed Feb 25, 2025
1 parent c3f0e67 commit 748ba93
Show file tree
Hide file tree
Showing 12 changed files with 563 additions and 61 deletions.
403 changes: 392 additions & 11 deletions Cargo.lock

Large diffs are not rendered by default.

7 changes: 6 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
[workspace]
members = ["utils", "recipe", "template", "process"]
members = [
"utils",
"recipe",
"template",
"process",
]

[workspace.package]
description = "A CLI tool built for creating Containerfile templates for ostree based atomic distros"
Expand Down
18 changes: 9 additions & 9 deletions bacon.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,13 @@ default_job = "clippy-all"
command = ["cargo", "check", "--color", "always"]
need_stdout = false
default_watch = false
watch = ["src", "process", "recipe", "template", "utils", "Cargo.toml", "build.rs"]
watch = ["src", "process", "recipe", "template", "utils", "buildkit-proto", "Cargo.toml", "build.rs"]

[jobs.check-all]
command = ["cargo", "check", "--all-features", "--color", "always"]
need_stdout = false
default_watch = false
watch = ["src", "process", "recipe", "template", "utils", "Cargo.toml", "build.rs"]
watch = ["src", "process", "recipe", "template", "utils", "buildkit-proto", "Cargo.toml", "build.rs"]

[jobs.clippy]
command = [
Expand All @@ -26,7 +26,7 @@ command = [
]
need_stdout = false
default_watch = false
watch = ["src", "process", "recipe", "template", "utils", "Cargo.toml", "build.rs"]
watch = ["src", "process", "recipe", "template", "utils", "buildkit-proto", "Cargo.toml", "build.rs"]

[jobs.clippy-all]
command = [
Expand All @@ -36,7 +36,7 @@ command = [
]
need_stdout = false
default_watch = false
watch = ["src", "process", "recipe", "template", "utils", "Cargo.toml", "build.rs"]
watch = ["src", "process", "recipe", "template", "utils", "buildkit-proto", "Cargo.toml", "build.rs"]

[jobs.test]
command = [
Expand All @@ -45,7 +45,7 @@ command = [
]
need_stdout = true
default_watch = false
watch = ["src", "process", "recipe", "template", "utils", "Cargo.toml", "build.rs", "test-files", "integration-tests"]
watch = ["src", "process", "recipe", "template", "utils", "buildkit-proto", "Cargo.toml", "build.rs", "test-files", "integration-tests"]

[jobs.test-all]
command = [
Expand All @@ -54,13 +54,13 @@ command = [
]
need_stdout = true
default_watch = false
watch = ["src", "process", "recipe", "template", "utils", "Cargo.toml", "build.rs", "test-files", "integration-tests"]
watch = ["src", "process", "recipe", "template", "utils", "buildkit-proto", "Cargo.toml", "build.rs", "test-files", "integration-tests"]

[jobs.doc]
command = ["cargo", "doc", "--color", "always", "--no-deps"]
need_stdout = false
default_watch = false
watch = ["src", "process", "recipe", "template", "utils", "Cargo.toml", "build.rs"]
watch = ["src", "process", "recipe", "template", "utils", "buildkit-proto", "Cargo.toml", "build.rs"]

# If the doc compiles, then it opens in your browser and bacon switches
# to the previous job
Expand All @@ -74,14 +74,14 @@ command = ["cargo", "install", "--path", ".", "--debug", "--locked", "--color",
need_stdout = false
allow_warnings = true
default_watch = false
watch = ["src", "process", "recipe", "template", "utils", "scripts", "Cargo.toml", "build.rs"]
watch = ["src", "process", "recipe", "template", "utils", "buildkit-proto", "scripts", "Cargo.toml", "build.rs"]

[jobs.install-all]
command = ["cargo", "install", "--all-features", "--path", ".", "--debug", "--locked", "--color", "always"]
need_stdout = false
allow_warnings = true
default_watch = false
watch = ["src", "process", "recipe", "template", "utils", "scripts", "Cargo.toml", "build.rs"]
watch = ["src", "process", "recipe", "template", "utils", "buildkit-proto", "scripts", "Cargo.toml", "build.rs"]

# You may define here keybindings that would be specific to
# a project, for example a shortcut to launch a specific job.
Expand Down
2 changes: 2 additions & 0 deletions process/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ path = "process.rs"
[dependencies]
anyhow = "1"
blue-build-utils = { version = "=0.9.8", path = "../utils" }
bollard = { version = "0.18", features = ["buildkit"] }
bollard-buildkit-proto = "0.5"
indicatif-log-bridge = "0.2"
log4rs = { version = "1", features = ["background_rotation"] }
nu-ansi-term = { version = "0.50", features = ["gnu_legacy"] }
Expand Down
16 changes: 9 additions & 7 deletions process/drivers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,14 +36,15 @@ use uuid::Uuid;
use crate::logging::Logger;

pub use self::{
buildah_driver::BuildahDriver, cosign_driver::CosignDriver, docker_driver::DockerDriver,
github_driver::GithubDriver, gitlab_driver::GitlabDriver, local_driver::LocalDriver,
podman_driver::PodmanDriver, skopeo_driver::SkopeoDriver, traits::*,
buildah_driver::BuildahDriver, buildkit_driver::BuildkitDriver, cosign_driver::CosignDriver,
docker_driver::DockerDriver, github_driver::GithubDriver, gitlab_driver::GitlabDriver,
local_driver::LocalDriver, podman_driver::PodmanDriver, skopeo_driver::SkopeoDriver, traits::*,
};
#[cfg(feature = "sigstore")]
pub use sigstore_driver::SigstoreDriver;

mod buildah_driver;
mod buildkit_driver;
mod cosign_driver;
mod docker_driver;
mod functions;
Expand Down Expand Up @@ -159,9 +160,9 @@ impl Driver {

impl_driver_init! {
INIT;
args.run_driver => SELECTED_RUN_DRIVER;
args.build_driver => SELECTED_BUILD_DRIVER;
args.inspect_driver => SELECTED_INSPECT_DRIVER;
args.run_driver => SELECTED_RUN_DRIVER;
args.signing_driver => SELECTED_SIGNING_DRIVER;
default => SELECTED_CI_DRIVER;
}
Expand Down Expand Up @@ -279,7 +280,7 @@ fn get_version_run_image(oci_ref: &Reference) -> Result<u64> {

let output = Driver::run_output(
&RunOpts::builder()
.image(oci_ref.to_string())
.image(oci_ref)
.args(bon::vec![
"/bin/bash",
"-c",
Expand All @@ -306,6 +307,7 @@ fn get_version_run_image(oci_ref: &Reference) -> Result<u64> {
macro_rules! impl_build_driver {
($func:ident($($args:expr),*)) => {
match Self::get_build_driver() {
BuildDriverType::Buildkit => BuildkitDriver::$func($($args,)*),
BuildDriverType::Buildah => BuildahDriver::$func($($args,)*),
BuildDriverType::Podman => PodmanDriver::$func($($args,)*),
BuildDriverType::Docker => DockerDriver::$func($($args,)*),
Expand Down Expand Up @@ -407,8 +409,8 @@ impl RunDriver for Driver {
impl_run_driver!(run_output(opts))
}

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

fn remove_container(container_id: &types::ContainerId) -> Result<()> {
Expand Down
49 changes: 49 additions & 0 deletions process/drivers/buildkit_driver.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
use miette::Result;

use super::{opts::RunOpts, BuildDriver, Driver, RunDriver};

pub struct BuildkitDriver;

impl BuildkitDriver {
/// Sets up buildkit container for building images.
///
/// # Errors
/// Errors if the buildkit container can't be created.
#[allow(clippy::missing_panics_doc)]
pub fn setup() -> Result<()> {
Driver::create_container(
&RunOpts::builder()
.image(&"moby/buildkit".try_into().expect("Valid image"))
.command("buildkit")
.build(),
)?;

Ok(())
}
}

impl BuildDriver for BuildkitDriver {
fn build(_opts: &super::opts::BuildOpts) -> Result<()> {
unimplemented!()
}

fn tag(_opts: &super::opts::TagOpts) -> Result<()> {
unimplemented!()
}

fn push(_opts: &super::opts::PushOpts) -> Result<()> {
unimplemented!()
}

fn login() -> Result<()> {
todo!()
}

fn prune(_opts: &super::opts::PruneOpts) -> Result<()> {
todo!()
}

fn build_tag_push(_opts: &super::opts::BuildTagPushOpts) -> Result<Vec<String>> {
todo!()
}
}
39 changes: 32 additions & 7 deletions process/drivers/docker_driver.rs
Original file line number Diff line number Diff line change
Expand Up @@ -483,7 +483,7 @@ impl RunDriver for DockerDriver {
add_cid(&cid);

let status = docker_run(opts, &cid_file)
.build_status(&*opts.image, "Running container")
.build_status(opts.image.to_string(), "Running container")
.into_diagnostic()?;

remove_cid(&cid);
Expand All @@ -507,19 +507,40 @@ impl RunDriver for DockerDriver {
Ok(output)
}

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

let output = {
let c = cmd!("docker", "create", image.to_string(), "bash",);
let c = cmd!(
"docker",
"create",
if opts.privileged => "--privileged",
if opts.remove => "--rm",
if opts.pull => "--pull=always",
if let Some(user) = opts.user.as_deref() => [
"--user",
user
],
for RunOptsVolume { path_or_vol_name, container_path } in opts.volumes.iter() => [
"--volume",
format!("{path_or_vol_name}:{container_path}"),
],
for RunOptsEnv { key, value } in opts.env_vars.iter() => [
"--env",
format!("{key}={value}"),
],
opts.image.to_string(),
if let Some(command) = opts.command.as_deref() => command,
for arg in opts.args.iter() => &**arg,
);
trace!("{c:?}");
c
}
.output()
.into_diagnostic()?;

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

Ok(ContainerId(
Expand Down Expand Up @@ -610,7 +631,10 @@ fn docker_run(opts: &RunOpts, cid_file: &Path) -> Command {
if opts.privileged => "--privileged",
if opts.remove => "--rm",
if opts.pull => "--pull=always",
if let Some(user) = opts.user.as_ref() => format!("--user={user}"),
if let Some(user) = opts.user.as_deref() => [
"--user",
user
],
for RunOptsVolume { path_or_vol_name, container_path } in opts.volumes.iter() => [
"--volume",
format!("{path_or_vol_name}:{container_path}"),
Expand All @@ -619,7 +643,8 @@ fn docker_run(opts: &RunOpts, cid_file: &Path) -> Command {
"--env",
format!("{key}={value}"),
],
&*opts.image,
opts.image.to_string(),
if let Some(command) = opts.command.as_deref() => command,
for arg in opts.args.iter() => &**arg,
);
trace!("{command:?}");
Expand Down
6 changes: 5 additions & 1 deletion process/drivers/opts/run.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
use std::borrow::Cow;

use bon::Builder;
use oci_distribution::Reference;

#[derive(Debug, Clone, Builder)]
pub struct RunOpts<'scope> {
#[builder(into)]
pub image: Cow<'scope, str>,
pub image: &'scope Reference,

#[builder(into)]
pub command: Option<Cow<'scope, str>>,

#[builder(default, into)]
pub args: Vec<Cow<'scope, str>>,
Expand Down
36 changes: 30 additions & 6 deletions process/drivers/podman_driver.rs
Original file line number Diff line number Diff line change
Expand Up @@ -415,7 +415,7 @@ impl RunDriver for PodmanDriver {
add_cid(&cid);

let status = podman_run(opts, &cid_file)
.build_status(&*opts.image, "Running container")
.build_status(opts.image.to_string(), "Running container")
.into_diagnostic()?;

remove_cid(&cid);
Expand Down Expand Up @@ -444,17 +444,38 @@ impl RunDriver for PodmanDriver {
Ok(output)
}

fn create_container(image: &Reference) -> Result<ContainerId> {
fn create_container(opts: &RunOpts) -> Result<ContainerId> {
let output = {
let c = cmd!("podman", "create", image.to_string(), "bash");
let c = cmd!(
"podman",
"create",
if opts.privileged => "--privileged",
if opts.remove => "--rm",
if opts.pull => "--pull=always",
if let Some(user) = opts.user.as_deref() => [
"--user",
user
],
for RunOptsVolume { path_or_vol_name, container_path } in opts.volumes.iter() => [
"--volume",
format!("{path_or_vol_name}:{container_path}"),
],
for RunOptsEnv { key, value } in opts.env_vars.iter() => [
"--env",
format!("{key}={value}"),
],
opts.image.to_string(),
if let Some(command) = opts.command.as_deref() => command,
for arg in opts.args.iter() => &**arg,
);
trace!("{c:?}");
c
}
.output()
.into_diagnostic()?;

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

Ok(ContainerId(
Expand Down Expand Up @@ -538,7 +559,10 @@ fn podman_run(opts: &RunOpts, cid_file: &Path) -> Command {
],
if opts.remove => "--rm",
if opts.pull => "--pull=always",
if let Some(user) = opts.user.as_ref() => format!("--user={user}"),
if let Some(user) = opts.user.as_deref() => [
"--user",
user
],
for RunOptsVolume { path_or_vol_name, container_path } in opts.volumes.iter() => [
"--volume",
format!("{path_or_vol_name}:{container_path}"),
Expand All @@ -547,7 +571,7 @@ fn podman_run(opts: &RunOpts, cid_file: &Path) -> Command {
"--env",
format!("{key}={value}"),
],
&*opts.image,
opts.image.to_string(),
for arg in opts.args.iter() => &**arg,
);
trace!("{command:?}");
Expand Down
Loading

0 comments on commit 748ba93

Please sign in to comment.