fix: Remove hard requirement for login creds to be able to push (#187)
Related to https://github.com/blue-build/github-action/issues/48
This commit is contained in:
parent
02b2fe5434
commit
9dd1ec90f4
8 changed files with 104 additions and 95 deletions
|
|
@ -12,7 +12,7 @@ version = "0.8.9"
|
||||||
[workspace.dependencies]
|
[workspace.dependencies]
|
||||||
anyhow = "1"
|
anyhow = "1"
|
||||||
chrono = "0.4"
|
chrono = "0.4"
|
||||||
clap = { version = "4", features = ["derive", "cargo", "unicode"] }
|
clap = "4"
|
||||||
colored = "2"
|
colored = "2"
|
||||||
env_logger = "0.11"
|
env_logger = "0.11"
|
||||||
format_serde_error = "0.3"
|
format_serde_error = "0.3"
|
||||||
|
|
@ -74,7 +74,7 @@ users = "0.11"
|
||||||
# Workspace dependencies
|
# Workspace dependencies
|
||||||
anyhow.workspace = true
|
anyhow.workspace = true
|
||||||
chrono.workspace = true
|
chrono.workspace = true
|
||||||
clap.workspace = true
|
clap = { workspace = true, features = ["derive", "cargo", "unicode", "env"] }
|
||||||
colored.workspace = true
|
colored.workspace = true
|
||||||
env_logger.workspace = true
|
env_logger.workspace = true
|
||||||
indexmap.workspace = true
|
indexmap.workspace = true
|
||||||
|
|
|
||||||
|
|
@ -7,11 +7,12 @@ use std::{
|
||||||
use anyhow::{bail, Context, Result};
|
use anyhow::{bail, Context, Result};
|
||||||
use blue_build_recipe::Recipe;
|
use blue_build_recipe::Recipe;
|
||||||
use blue_build_utils::constants::{
|
use blue_build_utils::constants::{
|
||||||
ARCHIVE_SUFFIX, BUILD_ID_LABEL, CI_DEFAULT_BRANCH, CI_PROJECT_NAME, CI_PROJECT_NAMESPACE,
|
ARCHIVE_SUFFIX, BB_PASSWORD, BB_REGISTRY, BB_REGISTRY_NAMESPACE, BB_USERNAME, BUILD_ID_LABEL,
|
||||||
CI_PROJECT_URL, CI_REGISTRY, CI_SERVER_HOST, CI_SERVER_PROTOCOL, CONFIG_PATH, CONTAINER_FILE,
|
CI_DEFAULT_BRANCH, CI_PROJECT_NAME, CI_PROJECT_NAMESPACE, CI_PROJECT_URL, CI_REGISTRY,
|
||||||
COSIGN_PATH, COSIGN_PRIVATE_KEY, GITHUB_REPOSITORY_OWNER, GITHUB_TOKEN,
|
CI_SERVER_HOST, CI_SERVER_PROTOCOL, CONFIG_PATH, CONTAINER_FILE, COSIGN_PATH,
|
||||||
GITHUB_TOKEN_ISSUER_URL, GITHUB_WORKFLOW_REF, GITIGNORE_PATH, LABELED_ERROR_MESSAGE,
|
COSIGN_PRIVATE_KEY, GITHUB_REPOSITORY_OWNER, GITHUB_TOKEN, GITHUB_TOKEN_ISSUER_URL,
|
||||||
NO_LABEL_ERROR_MESSAGE, RECIPE_FILE, RECIPE_PATH, SIGSTORE_ID_TOKEN,
|
GITHUB_WORKFLOW_REF, GITIGNORE_PATH, LABELED_ERROR_MESSAGE, NO_LABEL_ERROR_MESSAGE,
|
||||||
|
RECIPE_FILE, RECIPE_PATH, SIGSTORE_ID_TOKEN,
|
||||||
};
|
};
|
||||||
use clap::Args;
|
use clap::Args;
|
||||||
use colored::Colorize;
|
use colored::Colorize;
|
||||||
|
|
@ -20,7 +21,7 @@ use typed_builder::TypedBuilder;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
commands::generate::GenerateCommand,
|
commands::generate::GenerateCommand,
|
||||||
credentials,
|
credentials::{self, Credentials},
|
||||||
drivers::{
|
drivers::{
|
||||||
opts::{BuildTagPushOpts, CompressionType, GetMetadataOpts},
|
opts::{BuildTagPushOpts, CompressionType, GetMetadataOpts},
|
||||||
Driver,
|
Driver,
|
||||||
|
|
@ -78,26 +79,26 @@ pub struct BuildCommand {
|
||||||
archive: Option<PathBuf>,
|
archive: Option<PathBuf>,
|
||||||
|
|
||||||
/// The registry's domain name.
|
/// The registry's domain name.
|
||||||
#[arg(long)]
|
#[arg(long, env = BB_REGISTRY)]
|
||||||
#[builder(default, setter(into, strip_option))]
|
#[builder(default, setter(into, strip_option))]
|
||||||
registry: Option<String>,
|
registry: Option<String>,
|
||||||
|
|
||||||
/// The url path to your base
|
/// The url path to your base
|
||||||
/// project images.
|
/// project images.
|
||||||
#[arg(long)]
|
#[arg(long, env = BB_REGISTRY_NAMESPACE)]
|
||||||
#[builder(default, setter(into, strip_option))]
|
#[builder(default, setter(into, strip_option))]
|
||||||
#[arg(visible_alias("registry-path"))]
|
#[arg(visible_alias("registry-path"))]
|
||||||
registry_namespace: Option<String>,
|
registry_namespace: Option<String>,
|
||||||
|
|
||||||
/// The username to login to the
|
/// The username to login to the
|
||||||
/// container registry.
|
/// container registry.
|
||||||
#[arg(short = 'U', long)]
|
#[arg(short = 'U', long, env = BB_USERNAME, hide_env_values = true)]
|
||||||
#[builder(default, setter(into, strip_option))]
|
#[builder(default, setter(into, strip_option))]
|
||||||
username: Option<String>,
|
username: Option<String>,
|
||||||
|
|
||||||
/// The password to login to the
|
/// The password to login to the
|
||||||
/// container registry.
|
/// container registry.
|
||||||
#[arg(short = 'P', long)]
|
#[arg(short = 'P', long, env = BB_PASSWORD, hide_env_values = true)]
|
||||||
#[builder(default, setter(into, strip_option))]
|
#[builder(default, setter(into, strip_option))]
|
||||||
password: Option<String>,
|
password: Option<String>,
|
||||||
|
|
||||||
|
|
@ -129,6 +130,8 @@ impl BlueBuildCommand for BuildCommand {
|
||||||
check_cosign_files()?;
|
check_cosign_files()?;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Self::login()?;
|
||||||
|
|
||||||
// Check if the Containerfile exists
|
// Check if the Containerfile exists
|
||||||
// - If doesn't => *Build*
|
// - If doesn't => *Build*
|
||||||
// - If it does:
|
// - If it does:
|
||||||
|
|
@ -213,10 +216,6 @@ impl BuildCommand {
|
||||||
let tags = recipe.generate_tags(os_version);
|
let tags = recipe.generate_tags(os_version);
|
||||||
let image_name = self.generate_full_image_name(&recipe)?;
|
let image_name = self.generate_full_image_name(&recipe)?;
|
||||||
|
|
||||||
if self.push {
|
|
||||||
Self::login()?;
|
|
||||||
}
|
|
||||||
|
|
||||||
let opts = if let Some(archive_dir) = self.archive.as_ref() {
|
let opts = if let Some(archive_dir) = self.archive.as_ref() {
|
||||||
BuildTagPushOpts::builder()
|
BuildTagPushOpts::builder()
|
||||||
.archive_path(format!(
|
.archive_path(format!(
|
||||||
|
|
@ -253,32 +252,31 @@ impl BuildCommand {
|
||||||
trace!("BuildCommand::login()");
|
trace!("BuildCommand::login()");
|
||||||
info!("Attempting to login to the registry");
|
info!("Attempting to login to the registry");
|
||||||
|
|
||||||
let credentials = credentials::get()?;
|
if let Some(Credentials {
|
||||||
|
registry,
|
||||||
|
username,
|
||||||
|
password,
|
||||||
|
}) = credentials::get()
|
||||||
|
{
|
||||||
|
info!("Logging into the registry, {registry}");
|
||||||
|
Driver::get_build_driver().login()?;
|
||||||
|
|
||||||
let (registry, username, password) = (
|
trace!("cosign login -u {username} -p [MASKED] {registry}");
|
||||||
&credentials.registry,
|
let login_output = Command::new("cosign")
|
||||||
&credentials.username,
|
.arg("login")
|
||||||
&credentials.password,
|
.arg("-u")
|
||||||
);
|
.arg(username)
|
||||||
|
.arg("-p")
|
||||||
|
.arg(password)
|
||||||
|
.arg(registry)
|
||||||
|
.output()?;
|
||||||
|
|
||||||
info!("Logging into the registry, {registry}");
|
if !login_output.status.success() {
|
||||||
Driver::get_build_driver().login()?;
|
let err_output = String::from_utf8_lossy(&login_output.stderr);
|
||||||
|
bail!("Failed to login for cosign: {err_output}");
|
||||||
trace!("cosign login -u {username} -p [MASKED] {registry}");
|
}
|
||||||
let login_output = Command::new("cosign")
|
info!("Login success at {registry}");
|
||||||
.arg("login")
|
|
||||||
.arg("-u")
|
|
||||||
.arg(username)
|
|
||||||
.arg("-p")
|
|
||||||
.arg(password)
|
|
||||||
.arg(registry)
|
|
||||||
.output()?;
|
|
||||||
|
|
||||||
if !login_output.status.success() {
|
|
||||||
let err_output = String::from_utf8_lossy(&login_output.stderr);
|
|
||||||
bail!("Failed to login for cosign: {err_output}");
|
|
||||||
}
|
}
|
||||||
info!("Login success at {registry}");
|
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -128,9 +128,7 @@ pub fn set_user_creds(
|
||||||
///
|
///
|
||||||
/// # Errors
|
/// # Errors
|
||||||
/// Will error if there aren't any credentials available.
|
/// Will error if there aren't any credentials available.
|
||||||
pub fn get() -> Result<&'static Credentials> {
|
pub fn get() -> Option<&'static Credentials> {
|
||||||
trace!("credentials::get()");
|
trace!("credentials::get()");
|
||||||
ENV_CREDENTIALS
|
ENV_CREDENTIALS.as_ref()
|
||||||
.as_ref()
|
|
||||||
.ok_or_else(|| anyhow!("No credentials available"))
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ use log::{error, info, trace};
|
||||||
use semver::Version;
|
use semver::Version;
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
|
|
||||||
use crate::credentials;
|
use crate::credentials::{self, Credentials};
|
||||||
|
|
||||||
use super::{
|
use super::{
|
||||||
opts::{BuildOpts, PushOpts, TagOpts},
|
opts::{BuildOpts, PushOpts, TagOpts},
|
||||||
|
|
@ -109,22 +109,26 @@ impl BuildDriver for BuildahDriver {
|
||||||
fn login(&self) -> Result<()> {
|
fn login(&self) -> Result<()> {
|
||||||
trace!("BuildahDriver::login()");
|
trace!("BuildahDriver::login()");
|
||||||
|
|
||||||
let (registry, username, password) =
|
if let Some(Credentials {
|
||||||
credentials::get().map(|c| (&c.registry, &c.username, &c.password))?;
|
registry,
|
||||||
|
username,
|
||||||
|
password,
|
||||||
|
}) = credentials::get()
|
||||||
|
{
|
||||||
|
trace!("buildah login -u {username} -p [MASKED] {registry}");
|
||||||
|
let output = Command::new("buildah")
|
||||||
|
.arg("login")
|
||||||
|
.arg("-u")
|
||||||
|
.arg(username)
|
||||||
|
.arg("-p")
|
||||||
|
.arg(password)
|
||||||
|
.arg(registry)
|
||||||
|
.output()?;
|
||||||
|
|
||||||
trace!("buildah login -u {username} -p [MASKED] {registry}");
|
if !output.status.success() {
|
||||||
let output = Command::new("buildah")
|
let err_out = String::from_utf8_lossy(&output.stderr);
|
||||||
.arg("login")
|
bail!("Failed to login for buildah: {err_out}");
|
||||||
.arg("-u")
|
}
|
||||||
.arg(username)
|
|
||||||
.arg("-p")
|
|
||||||
.arg(password)
|
|
||||||
.arg(registry)
|
|
||||||
.output()?;
|
|
||||||
|
|
||||||
if !output.status.success() {
|
|
||||||
let err_out = String::from_utf8_lossy(&output.stderr);
|
|
||||||
bail!("Failed to login for buildah: {err_out}");
|
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@ use once_cell::sync::Lazy;
|
||||||
use semver::Version;
|
use semver::Version;
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
|
|
||||||
use crate::image_metadata::ImageMetadata;
|
use crate::{credentials::Credentials, image_metadata::ImageMetadata};
|
||||||
|
|
||||||
use super::{
|
use super::{
|
||||||
credentials,
|
credentials,
|
||||||
|
|
@ -169,22 +169,26 @@ impl BuildDriver for DockerDriver {
|
||||||
fn login(&self) -> Result<()> {
|
fn login(&self) -> Result<()> {
|
||||||
trace!("DockerDriver::login()");
|
trace!("DockerDriver::login()");
|
||||||
|
|
||||||
let (registry, username, password) =
|
if let Some(Credentials {
|
||||||
credentials::get().map(|c| (&c.registry, &c.username, &c.password))?;
|
registry,
|
||||||
|
username,
|
||||||
|
password,
|
||||||
|
}) = credentials::get()
|
||||||
|
{
|
||||||
|
trace!("docker login -u {username} -p [MASKED] {registry}");
|
||||||
|
let output = Command::new("docker")
|
||||||
|
.arg("login")
|
||||||
|
.arg("-u")
|
||||||
|
.arg(username)
|
||||||
|
.arg("-p")
|
||||||
|
.arg(password)
|
||||||
|
.arg(registry)
|
||||||
|
.output()?;
|
||||||
|
|
||||||
trace!("docker login -u {username} -p [MASKED] {registry}");
|
if !output.status.success() {
|
||||||
let output = Command::new("docker")
|
let err_out = String::from_utf8_lossy(&output.stderr);
|
||||||
.arg("login")
|
bail!("Failed to login for docker: {err_out}");
|
||||||
.arg("-u")
|
}
|
||||||
.arg(username)
|
|
||||||
.arg("-p")
|
|
||||||
.arg(password)
|
|
||||||
.arg(registry)
|
|
||||||
.output()?;
|
|
||||||
|
|
||||||
if !output.status.success() {
|
|
||||||
let err_out = String::from_utf8_lossy(&output.stderr);
|
|
||||||
bail!("Failed to login for docker: {err_out}");
|
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@ use log::{debug, error, info, trace};
|
||||||
use semver::Version;
|
use semver::Version;
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
|
|
||||||
use crate::image_metadata::ImageMetadata;
|
use crate::{credentials::Credentials, image_metadata::ImageMetadata};
|
||||||
|
|
||||||
use super::{
|
use super::{
|
||||||
credentials,
|
credentials,
|
||||||
|
|
@ -120,22 +120,26 @@ impl BuildDriver for PodmanDriver {
|
||||||
fn login(&self) -> Result<()> {
|
fn login(&self) -> Result<()> {
|
||||||
trace!("PodmanDriver::login()");
|
trace!("PodmanDriver::login()");
|
||||||
|
|
||||||
let (registry, username, password) =
|
if let Some(Credentials {
|
||||||
credentials::get().map(|c| (&c.registry, &c.username, &c.password))?;
|
registry,
|
||||||
|
username,
|
||||||
|
password,
|
||||||
|
}) = credentials::get()
|
||||||
|
{
|
||||||
|
trace!("podman login -u {username} -p [MASKED] {registry}");
|
||||||
|
let output = Command::new("podman")
|
||||||
|
.arg("login")
|
||||||
|
.arg("-u")
|
||||||
|
.arg(username)
|
||||||
|
.arg("-p")
|
||||||
|
.arg(password)
|
||||||
|
.arg(registry)
|
||||||
|
.output()?;
|
||||||
|
|
||||||
trace!("podman login -u {username} -p [MASKED] {registry}");
|
if !output.status.success() {
|
||||||
let output = Command::new("podman")
|
let err_out = String::from_utf8_lossy(&output.stderr);
|
||||||
.arg("login")
|
bail!("Failed to login for podman: {err_out}");
|
||||||
.arg("-u")
|
}
|
||||||
.arg(username)
|
|
||||||
.arg("-p")
|
|
||||||
.arg(password)
|
|
||||||
.arg(registry)
|
|
||||||
.output()?;
|
|
||||||
|
|
||||||
if !output.status.success() {
|
|
||||||
let err_out = String::from_utf8_lossy(&output.stderr);
|
|
||||||
bail!("Failed to login for podman: {err_out}");
|
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,7 @@ which = "6"
|
||||||
|
|
||||||
anyhow.workspace = true
|
anyhow.workspace = true
|
||||||
chrono.workspace = true
|
chrono.workspace = true
|
||||||
|
clap = { workspace = true, features = ["derive"] }
|
||||||
colored.workspace = true
|
colored.workspace = true
|
||||||
env_logger.workspace = true
|
env_logger.workspace = true
|
||||||
format_serde_error.workspace = true
|
format_serde_error.workspace = true
|
||||||
|
|
@ -25,10 +26,6 @@ serde.workspace = true
|
||||||
serde_yaml.workspace = true
|
serde_yaml.workspace = true
|
||||||
serde_json.workspace = true
|
serde_json.workspace = true
|
||||||
|
|
||||||
[dependencies.clap]
|
|
||||||
workspace = true
|
|
||||||
features = ["derive"]
|
|
||||||
|
|
||||||
[build-dependencies]
|
[build-dependencies]
|
||||||
syntect = "5.2.0"
|
syntect = "5.2.0"
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,10 @@ pub const IMAGE_VERSION_LABEL: &str = "org.opencontainers.image.version";
|
||||||
|
|
||||||
// BlueBuild vars
|
// BlueBuild vars
|
||||||
pub const BB_BUILDKIT_CACHE_GHA: &str = "BB_BUILDKIT_CACHE_GHA";
|
pub const BB_BUILDKIT_CACHE_GHA: &str = "BB_BUILDKIT_CACHE_GHA";
|
||||||
|
pub const BB_PASSWORD: &str = "BB_PASSWORD";
|
||||||
|
pub const BB_REGISTRY: &str = "BB_REGISTRY";
|
||||||
|
pub const BB_REGISTRY_NAMESPACE: &str = "BB_REGISTRY_NAMESPACE";
|
||||||
|
pub const BB_USERNAME: &str = "BB_USERNAME";
|
||||||
|
|
||||||
// Docker vars
|
// Docker vars
|
||||||
pub const DOCKER_HOST: &str = "DOCKER_HOST";
|
pub const DOCKER_HOST: &str = "DOCKER_HOST";
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue