feat: Add ability to mount secrets
This commit is contained in:
parent
22ef8392b7
commit
4fabd3e5db
27 changed files with 463 additions and 69 deletions
|
|
@ -20,7 +20,6 @@ os_pipe = { version = "1", features = ["io_safety"] }
|
|||
rand = "0.9"
|
||||
signal-hook = { version = "0.3", features = ["extended-siginfo"] }
|
||||
sigstore = { version = "0.11", features = ["full-rustls-tls", "cached-client", "sigstore-trust-root", "sign"], default-features = false }
|
||||
zeroize = { version = "1", features = ["aarch64", "derive", "serde"] }
|
||||
|
||||
cached.workspace = true
|
||||
chrono.workspace = true
|
||||
|
|
@ -42,6 +41,7 @@ tokio.workspace = true
|
|||
bon.workspace = true
|
||||
users.workspace = true
|
||||
uuid.workspace = true
|
||||
zeroize.workspace = true
|
||||
|
||||
[dev-dependencies]
|
||||
rstest.workspace = true
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ use std::{
|
|||
time::Duration,
|
||||
};
|
||||
|
||||
use blue_build_utils::semver::Version;
|
||||
use blue_build_utils::{BUILD_ID, semver::Version};
|
||||
use bon::{Builder, bon};
|
||||
use cached::proc_macro::cached;
|
||||
use clap::Args;
|
||||
|
|
@ -69,9 +69,6 @@ static SELECTED_SIGNING_DRIVER: std::sync::LazyLock<RwLock<Option<SigningDriverT
|
|||
static SELECTED_CI_DRIVER: std::sync::LazyLock<RwLock<Option<CiDriverType>>> =
|
||||
std::sync::LazyLock::new(|| RwLock::new(None));
|
||||
|
||||
/// UUID used to mark the current builds
|
||||
static BUILD_ID: std::sync::LazyLock<Uuid> = std::sync::LazyLock::new(Uuid::new_v4);
|
||||
|
||||
/// Args for selecting the various drivers to use for runtime.
|
||||
///
|
||||
/// If the args are left uninitialized, the program will determine
|
||||
|
|
|
|||
|
|
@ -1,11 +1,12 @@
|
|||
use std::{io::Write, process::Stdio};
|
||||
|
||||
use blue_build_utils::{credentials::Credentials, semver::Version};
|
||||
use blue_build_utils::{credentials::Credentials, secret::SecretArgs, semver::Version};
|
||||
use colored::Colorize;
|
||||
use comlexr::cmd;
|
||||
use log::{debug, error, info, trace};
|
||||
use miette::{IntoDiagnostic, Result, bail, miette};
|
||||
use miette::{Context, IntoDiagnostic, Result, bail, miette};
|
||||
use serde::Deserialize;
|
||||
use tempfile::TempDir;
|
||||
|
||||
use crate::{drivers::types::Platform, logging::CommandLogging};
|
||||
|
||||
|
|
@ -50,9 +51,14 @@ impl BuildDriver for BuildahDriver {
|
|||
fn build(opts: &BuildOpts) -> Result<()> {
|
||||
trace!("BuildahDriver::build({opts:#?})");
|
||||
|
||||
let temp_dir = TempDir::new()
|
||||
.into_diagnostic()
|
||||
.wrap_err("Failed to create temporary directory for secrets")?;
|
||||
|
||||
let command = cmd!(
|
||||
"buildah",
|
||||
"build",
|
||||
for opts.secrets.args(&temp_dir)?,
|
||||
if !matches!(opts.platform, Platform::Native) => [
|
||||
"--platform",
|
||||
opts.platform.to_string(),
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ use blue_build_utils::{
|
|||
constants::{BLUE_BUILD, DOCKER_HOST, GITHUB_ACTIONS},
|
||||
credentials::Credentials,
|
||||
get_env_var,
|
||||
secret::SecretArgs,
|
||||
semver::Version,
|
||||
string_vec,
|
||||
};
|
||||
|
|
@ -194,6 +195,10 @@ impl BuildDriver for DockerDriver {
|
|||
fn build(opts: &BuildOpts) -> Result<()> {
|
||||
trace!("DockerDriver::build({opts:#?})");
|
||||
|
||||
let temp_dir = TempDir::new()
|
||||
.into_diagnostic()
|
||||
.wrap_err("Failed to create temporary directory for secrets")?;
|
||||
|
||||
if opts.squash {
|
||||
warn!("Squash is deprecated for docker so this build will not squash");
|
||||
}
|
||||
|
|
@ -209,6 +214,7 @@ impl BuildDriver for DockerDriver {
|
|||
"-t",
|
||||
opts.image.to_string(),
|
||||
"-f",
|
||||
for opts.secrets.args(&temp_dir)?,
|
||||
if let Some(cache_from) = opts.cache_from.as_ref() => [
|
||||
"--cache-from",
|
||||
format!(
|
||||
|
|
@ -381,6 +387,10 @@ impl BuildDriver for DockerDriver {
|
|||
fn build_tag_push(opts: &BuildTagPushOpts) -> Result<Vec<String>> {
|
||||
trace!("DockerDriver::build_tag_push({opts:#?})");
|
||||
|
||||
let temp_dir = TempDir::new()
|
||||
.into_diagnostic()
|
||||
.wrap_err("Failed to create temporary directory for secrets")?;
|
||||
|
||||
if opts.squash {
|
||||
warn!("Squash is deprecated for docker so this build will not squash");
|
||||
}
|
||||
|
|
@ -391,7 +401,7 @@ impl BuildDriver for DockerDriver {
|
|||
|
||||
let first_image = final_images.first().unwrap();
|
||||
|
||||
let status = build_tag_push_cmd(opts, first_image)
|
||||
let status = build_tag_push_cmd(opts, first_image, &temp_dir)?
|
||||
.build_status(first_image, "Building Image")
|
||||
.into_diagnostic()?;
|
||||
|
||||
|
|
@ -408,13 +418,18 @@ impl BuildDriver for DockerDriver {
|
|||
}
|
||||
}
|
||||
|
||||
fn build_tag_push_cmd(opts: &BuildTagPushOpts<'_>, first_image: &str) -> Command {
|
||||
fn build_tag_push_cmd(
|
||||
opts: &BuildTagPushOpts<'_>,
|
||||
first_image: &str,
|
||||
temp_dir: &TempDir,
|
||||
) -> Result<Command> {
|
||||
let c = cmd!(
|
||||
"docker",
|
||||
"buildx",
|
||||
format!("--builder={BLUE_BUILD}"),
|
||||
"build",
|
||||
".",
|
||||
for opts.secrets.args(temp_dir)?,
|
||||
match &opts.image {
|
||||
ImageRef::Remote(_remote) if opts.push => [
|
||||
"--output",
|
||||
|
|
@ -459,7 +474,7 @@ fn build_tag_push_cmd(opts: &BuildTagPushOpts<'_>, first_image: &str) -> Command
|
|||
],
|
||||
);
|
||||
trace!("{c:?}");
|
||||
c
|
||||
Ok(c)
|
||||
}
|
||||
|
||||
fn get_final_images(opts: &BuildTagPushOpts<'_>) -> Vec<String> {
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
use std::{borrow::Cow, path::Path};
|
||||
use std::{borrow::Cow, collections::HashSet, path::Path};
|
||||
|
||||
use blue_build_utils::secret::Secret;
|
||||
use bon::Builder;
|
||||
use oci_distribution::Reference;
|
||||
|
||||
|
|
@ -33,6 +34,9 @@ pub struct BuildOpts<'scope> {
|
|||
|
||||
#[builder(into)]
|
||||
pub cache_to: Option<&'scope Reference>,
|
||||
|
||||
#[builder(default)]
|
||||
pub secrets: HashSet<&'scope Secret>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Builder)]
|
||||
|
|
@ -110,4 +114,8 @@ pub struct BuildTagPushOpts<'scope> {
|
|||
|
||||
/// Cache layers to the registry.
|
||||
pub cache_to: Option<&'scope Reference>,
|
||||
|
||||
/// Secrets to mount
|
||||
#[builder(default)]
|
||||
pub secrets: HashSet<&'scope Secret>,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
use std::{borrow::Cow, path::Path};
|
||||
use std::{borrow::Cow, collections::HashSet, path::Path};
|
||||
|
||||
use blue_build_utils::secret::Secret;
|
||||
use bon::Builder;
|
||||
use oci_distribution::Reference;
|
||||
|
||||
|
|
@ -55,6 +56,9 @@ pub struct RechunkOpts<'scope> {
|
|||
|
||||
/// Cache layers to the registry.
|
||||
pub cache_to: Option<&'scope Reference>,
|
||||
|
||||
#[builder(default)]
|
||||
pub secrets: HashSet<&'scope Secret>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Builder)]
|
||||
|
|
|
|||
|
|
@ -7,14 +7,14 @@ use std::{
|
|||
|
||||
use blue_build_utils::{
|
||||
constants::SUDO_ASKPASS, credentials::Credentials, has_env_var, running_as_root,
|
||||
semver::Version,
|
||||
secret::SecretArgs, semver::Version,
|
||||
};
|
||||
use cached::proc_macro::cached;
|
||||
use colored::Colorize;
|
||||
use comlexr::{cmd, pipe};
|
||||
use indicatif::{ProgressBar, ProgressStyle};
|
||||
use log::{debug, error, info, trace};
|
||||
use miette::{IntoDiagnostic, Report, Result, bail, miette};
|
||||
use miette::{Context, IntoDiagnostic, Report, Result, bail, miette};
|
||||
use oci_distribution::Reference;
|
||||
use serde::Deserialize;
|
||||
use tempfile::TempDir;
|
||||
|
|
@ -137,6 +137,10 @@ impl BuildDriver for PodmanDriver {
|
|||
fn build(opts: &BuildOpts) -> Result<()> {
|
||||
trace!("PodmanDriver::build({opts:#?})");
|
||||
|
||||
let temp_dir = TempDir::new()
|
||||
.into_diagnostic()
|
||||
.wrap_err("Failed to create temporary directory for secrets")?;
|
||||
|
||||
let use_sudo = opts.privileged && !running_as_root();
|
||||
let command = cmd!(
|
||||
if use_sudo {
|
||||
|
|
@ -149,7 +153,10 @@ impl BuildDriver for PodmanDriver {
|
|||
"-p",
|
||||
SUDO_PROMPT,
|
||||
],
|
||||
if use_sudo => "podman",
|
||||
if use_sudo => [
|
||||
"--preserve-env",
|
||||
"podman",
|
||||
],
|
||||
"build",
|
||||
if !matches!(opts.platform, Platform::Native) => [
|
||||
"--platform",
|
||||
|
|
@ -178,6 +185,7 @@ impl BuildDriver for PodmanDriver {
|
|||
&*opts.containerfile,
|
||||
"-t",
|
||||
opts.image.to_string(),
|
||||
for opts.secrets.args(&temp_dir)?,
|
||||
".",
|
||||
);
|
||||
|
||||
|
|
@ -409,11 +417,11 @@ impl ContainerMountDriver for PodmanDriver {
|
|||
} else {
|
||||
"podman"
|
||||
},
|
||||
if use_sudo && has_env_var(SUDO_ASKPASS) => [
|
||||
"-A",
|
||||
"-p",
|
||||
SUDO_PROMPT,
|
||||
],
|
||||
if use_sudo && has_env_var(SUDO_ASKPASS) => [
|
||||
"-A",
|
||||
"-p",
|
||||
SUDO_PROMPT,
|
||||
],
|
||||
if use_sudo => "podman",
|
||||
"mount",
|
||||
opts.container_id,
|
||||
|
|
|
|||
|
|
@ -128,6 +128,7 @@ pub trait BuildDriver: PrivateDriver {
|
|||
.squash(opts.squash)
|
||||
.maybe_cache_from(opts.cache_from)
|
||||
.maybe_cache_to(opts.cache_to)
|
||||
.secrets(opts.secrets.clone())
|
||||
.build();
|
||||
|
||||
info!("Building image {}", opts.image);
|
||||
|
|
@ -289,6 +290,7 @@ pub trait RechunkDriver: RunDriver + BuildDriver + ContainerMountDriver {
|
|||
.privileged(true)
|
||||
.squash(true)
|
||||
.host_network(true)
|
||||
.secrets(opts.secrets.clone())
|
||||
.build(),
|
||||
)?;
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue