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: Add missing container tags #37

Merged
merged 3 commits into from
Feb 3, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
12 changes: 7 additions & 5 deletions src/commands/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,7 @@ impl BuildCommand {
trace!("recipe: {recipe:#?}");

// Get values for image
let tags = recipe.generate_tags();
let tags = recipe.generate_tags()?;
let image_name = self.generate_full_image_name(&recipe)?;
let first_image_name = if self.archive.is_some() {
image_name.to_string()
Expand Down Expand Up @@ -271,7 +271,7 @@ impl BuildCommand {
trace!("BuildCommand::build_image()");
let recipe: Recipe = serde_yaml::from_str(fs::read_to_string(&self.recipe)?.as_str())?;

let tags = recipe.generate_tags();
let tags = recipe.generate_tags()?;

let image_name = self.generate_full_image_name(&recipe)?;

Expand Down Expand Up @@ -590,7 +590,8 @@ fn sign_images(image_name: &str, tag: Option<&str>) -> Result<()> {
}
}
(_, _, _, _, _, _, Ok(github_event_name), Ok(github_ref_name), Ok(_))
if github_event_name != "pull_request" && github_ref_name == "live" =>
if github_event_name != "pull_request"
&& (github_ref_name == "live" || github_ref_name == "main") =>
{
trace!("GITHUB_EVENT_NAME={github_event_name}, GITHUB_REF_NAME={github_ref_name}");

Expand Down Expand Up @@ -663,8 +664,9 @@ fn check_cosign_files() -> Result<()> {
env::var("GITHUB_REF_NAME").ok(),
env::var("COSIGN_PRIVATE_KEY").ok(),
) {
(Some(github_event_name), Some(github_ref), Some(_))
if github_event_name != "pull_request" && github_ref == "live" =>
(Some(github_event_name), Some(github_ref_name), Some(_))
if github_event_name != "pull_request"
&& (github_ref_name == "live" || github_ref_name == "main") =>
{
env::set_var("COSIGN_PASSWORD", "");
env::set_var("COSIGN_YES", "true");
Expand Down
87 changes: 73 additions & 14 deletions src/module_recipe.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,22 @@
use std::{borrow::Cow, env, fs, path::Path, process};

use std::{
borrow::Cow,
collections::HashMap,
env, fs,
path::Path,
process::{self, Command},
};

use anyhow::{bail, Result};
use chrono::Local;
use indexmap::IndexMap;
use log::{debug, error, trace, warn};
use log::{debug, error, info, trace, warn};
use serde::{Deserialize, Serialize};
use serde_json::Value as JsonValue;
use serde_yaml::Value;
use typed_builder::TypedBuilder;

use crate::ops::check_command_exists;

#[derive(Default, Serialize, Clone, Deserialize, Debug, TypedBuilder)]
pub struct Recipe<'a> {
#[builder(setter(into))]
Expand Down Expand Up @@ -36,13 +46,12 @@ pub struct Recipe<'a> {
}

impl<'a> Recipe<'a> {
#[must_use]
pub fn generate_tags(&self) -> Vec<String> {
pub fn generate_tags(&self) -> Result<Vec<String>> {
trace!("Recipe::generate_tags()");
trace!("Generating image tags for {}", &self.name);

let mut tags: Vec<String> = Vec::new();
let image_version = &self.image_version;
let image_version = self.get_os_version()?;
let timestamp = Local::now().format("%Y%m%d").to_string();

if let (Ok(commit_branch), Ok(default_branch), Ok(commit_sha), Ok(pipeline_source)) = (
Expand All @@ -65,11 +74,12 @@ impl<'a> Recipe<'a> {
if default_branch == commit_branch {
debug!("Running on the default branch");
tags.push(image_version.to_string());
tags.push(format!("{image_version}-{timestamp}"));
tags.push(format!("{timestamp}-{image_version}"));
tags.push("latest".into());
tags.push(timestamp);
} else {
debug!("Running on branch {commit_branch}");
tags.push(format!("{commit_branch}-{image_version}"));
tags.push(format!("br-{commit_branch}-{image_version}"));
}

tags.push(format!("{commit_sha}-{image_version}"));
Expand All @@ -93,27 +103,29 @@ impl<'a> Recipe<'a> {
if github_event_name == "pull_request" {
debug!("Running in a PR");
tags.push(format!("pr-{github_event_number}-{image_version}"));
} else if github_ref_name == "live" {
} else if github_ref_name == "live" || github_ref_name == "main" {
tags.push(image_version.to_string());
tags.push(format!("{image_version}-{timestamp}"));
tags.push("latest".to_string());
tags.push(format!("{timestamp}-{image_version}"));
tags.push("latest".into());
tags.push(timestamp);
} else {
tags.push(format!("br-{github_ref_name}-{image_version}"));
}
tags.push(format!("{short_sha}-{image_version}"));
} else {
warn!("Running locally");
tags.push(format!("{image_version}-local"));
tags.push(format!("local-{image_version}"));
}
debug!("Finished generating tags!");
debug!("Tags: {tags:#?}");
tags

Ok(tags)
}

/// # Parse a recipe file
/// #
/// # Errors
pub fn parse<P: AsRef<Path>>(path: &P) -> anyhow::Result<Self> {
pub fn parse<P: AsRef<Path>>(path: &P) -> Result<Self> {
let file_path = if Path::new(path.as_ref()).is_absolute() {
path.as_ref().to_path_buf()
} else {
Expand All @@ -136,6 +148,33 @@ impl<'a> Recipe<'a> {
process::exit(1);
})
}

fn get_os_version(&self) -> Result<String> {
trace!("Recipe::get_os_version()");
check_command_exists("skopeo")?;

gmpinder marked this conversation as resolved.
Show resolved Hide resolved
let base_image = self.base_image.as_ref();
let image_version = self.image_version.as_ref();

info!("Retrieving information from {base_image}:{image_version}, this will take a bit");

let output = Command::new("skopeo")
.arg("inspect")
.arg(format!("docker://{base_image}:{image_version}"))
.output()?;

if !output.status.success() {
bail!("Failed to get image information for {base_image}:{image_version}");
}

let inspection: ImageInspection =
serde_json::from_str(String::from_utf8(output.stdout)?.as_str())?;

Ok(inspection.get_version().unwrap_or_else(|| {
warn!("Version label does not exist on image, using version in recipe");
image_version.to_string()
}))
}
}

#[derive(Default, Serialize, Clone, Deserialize, Debug, TypedBuilder)]
Expand All @@ -158,3 +197,23 @@ pub struct Module {
#[builder(default, setter(into))]
pub config: IndexMap<String, Value>,
}

#[derive(Deserialize, Debug, Clone)]
struct ImageInspection {
#[serde(alias = "Labels")]
labels: HashMap<String, JsonValue>,
}

impl ImageInspection {
pub fn get_version(&self) -> Option<String> {
Some(
self.labels
.get("org.opencontainers.image.version")?
.as_str()
.map(|v| v.to_string())?
.split('.')
.take(1)
.collect(),
)
}
}
1 change: 0 additions & 1 deletion templates/Containerfile
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
FROM {{ recipe.base_image }}:{{ recipe.image_version }}

LABEL org.opencontainers.image.title="{{ recipe.name }}"
LABEL org.opencontainers.image.version="{{ recipe.image_version }}"
LABEL org.opencontainers.image.description="{{ recipe.description }}"
LABEL io.artifacthub.package.readme-url=https://raw.githubusercontent.com/ublue-os/startingpoint/main/README.md
LABEL io.artifacthub.package.logo-url=https://avatars.githubusercontent.com/u/120078124?s=200&v=4
Expand Down
Loading