Skip to content

Commit

Permalink
feat: Support versioned modules
Browse files Browse the repository at this point in the history
  • Loading branch information
gmpinder committed Dec 24, 2024
1 parent 8325de0 commit 11b846c
Show file tree
Hide file tree
Showing 6 changed files with 108 additions and 18 deletions.
25 changes: 18 additions & 7 deletions recipe/src/module.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,15 @@ use serde_yaml::Value;

use crate::{base_recipe_path, AkmodsInfo, ModuleExt};

#[derive(Serialize, Deserialize, Debug, Clone, Builder, Default)]
mod type_ver;

pub use type_ver::*;

#[derive(Serialize, Deserialize, Debug, Clone, Builder)]
pub struct ModuleRequiredFields<'a> {
#[builder(into)]
#[serde(rename = "type")]
pub module_type: Cow<'a, str>,
pub module_type: ModuleTypeVersion<'a>,

#[builder(into)]
#[serde(skip_serializing_if = "Option::is_none")]
Expand All @@ -38,7 +42,7 @@ const fn is_false(b: &bool) -> bool {
impl<'a> ModuleRequiredFields<'a> {
#[must_use]
pub fn get_module_type_list(&'a self, typ: &str, list_key: &str) -> Option<Vec<String>> {
if self.module_type == typ {
if self.module_type.typ() == typ {
Some(
self.config
.get(list_key)?
Expand Down Expand Up @@ -217,7 +221,7 @@ impl Module<'_> {
required_fields: None,
from_file: Some(file_name),
} => {
let file_name = PathBuf::from(file_name.as_ref());
let file_name = PathBuf::from(&**file_name);
if traversed_files.contains(&file_name) {
bail!(
"{} File {} has already been parsed:\n{traversed_files:?}",
Expand Down Expand Up @@ -260,14 +264,21 @@ impl Module<'_> {
}

#[must_use]
#[allow(clippy::missing_panics_doc)]
pub fn example() -> Self {
Self::builder()
.required_fields(
ModuleRequiredFields::builder()
.module_type("module-name")
.module_type("script")
.config(IndexMap::from_iter([
("module".to_string(), Value::String("config".to_string())),
("goes".to_string(), Value::String("here".to_string())),
(
"snippets".to_string(),
Value::Sequence(bon::vec!["echo 'Hello World!'"]),
),
(
"scripts".to_string(),
Value::Sequence(bon::vec!["install-program.sh"]),
),
]))
.build(),
)
Expand Down
78 changes: 78 additions & 0 deletions recipe/src/module/type_ver.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
use std::borrow::Cow;

use serde::{Deserialize, Deserializer, Serialize};

#[derive(Debug, Clone)]
pub struct ModuleTypeVersion<'scope> {
typ: Cow<'scope, str>,
version: Cow<'scope, str>,
}

impl<'scope> ModuleTypeVersion<'scope> {
#[must_use]
pub fn typ(&self) -> &str {
&self.typ
}

#[must_use]
pub fn version(&self) -> &str {
&self.version
}
}

impl std::fmt::Display for ModuleTypeVersion<'_> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}@{}", &self.typ, &self.version)
}
}

impl<'scope> From<&'scope str> for ModuleTypeVersion<'scope> {
fn from(s: &'scope str) -> Self {
if let Some((typ, version)) = s.split_once('@') {
Self {
typ: Cow::Borrowed(typ),
version: Cow::Borrowed(version),
}
} else {
Self {
typ: Cow::Borrowed(s),
version: Cow::Owned("latest".into()),
}
}
}
}

impl From<String> for ModuleTypeVersion<'_> {
fn from(s: String) -> Self {
if let Some((typ, version)) = s.split_once('@') {
Self {
typ: Cow::Owned(typ.to_owned()),
version: Cow::Owned(version.to_owned()),
}
} else {
Self {
typ: Cow::Owned(s),
version: Cow::Owned("latest".into()),
}
}
}
}

impl Serialize for ModuleTypeVersion<'_> {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
serializer.serialize_str(&self.to_string())
}
}

impl<'de> Deserialize<'de> for ModuleTypeVersion<'_> {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
let value: String = Deserialize::deserialize(deserializer)?;
Ok(value.into())
}
}
2 changes: 1 addition & 1 deletion recipe/src/module_ext.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ impl ModuleExt<'_> {
module
.required_fields
.as_ref()
.is_some_and(|rf| rf.module_type == "akmods")
.is_some_and(|rf| rf.module_type.typ() == "akmods")
})
.filter_map(|module| {
Some(
Expand Down
2 changes: 1 addition & 1 deletion recipe/src/stage.rs
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ impl Stage<'_> {
required_fields: None,
from_file: Some(file_name),
} => {
let file_name = PathBuf::from(file_name.as_ref());
let file_name = PathBuf::from(&**file_name);
if traversed_files.contains(&file_name) {
bail!(
"{} File {} has already been parsed:\n{traversed_files:?}",
Expand Down
18 changes: 9 additions & 9 deletions template/templates/modules/modules.j2
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@
ARG CACHEBUST="{{ build_id }}"
{%- endif %}

{%- if module.module_type == "containerfile" %}
{%- if module.module_type.typ() == "containerfile" %}
{%- include "modules/containerfile/containerfile.j2" %}
{%- else if module.module_type == "copy" %}
{%- else if module.module_type.typ() == "copy" %}
{%- include "modules/copy/copy.j2" %}
{%- else %}
RUN \
Expand All @@ -22,15 +22,15 @@ RUN \
{%- else if module.is_local_source() %}
--mount=type=bind,from=stage-modules,src=/modules,dst=/tmp/modules,rw \
{%- else %}
--mount=type=bind,from=ghcr.io/blue-build/modules/{{ module.module_type }}:latest,src=/modules,dst=/tmp/modules,rw \
--mount=type=bind,from={{ blue_build_utils::constants::BLUE_BUILD_MODULE_IMAGE_REF }}/{{ module.module_type.typ() }}:{{ module.module_type.version() }},src=/modules,dst=/tmp/modules,rw \
{%- endif %}
{%- if module.module_type == "akmods" %}
{%- if module.module_type.typ() == "akmods" %}
--mount=type=bind,from=stage-akmods-{{ module.generate_akmods_info(os_version).stage_name }},src=/rpms,dst=/tmp/rpms,rw \
{%- endif %}
--mount=type=bind,from={{ build_scripts_image }},src=/scripts/,dst=/tmp/scripts/ \
--mount=type=cache,dst=/var/cache/rpm-ostree,id=rpm-ostree-cache-{{ recipe.name }}-{{ recipe.image_version }},sharing=locked \
--mount=type=cache,dst=/var/cache/libdnf5,id=dnf-cache-{{ recipe.name }}-{{ recipe.image_version }},sharing=locked \
/tmp/scripts/run_module.sh '{{ module.module_type }}' '{{ module|json|safe }}'
/tmp/scripts/run_module.sh '{{ module.module_type.typ() }}' '{{ module|json|safe }}'
{%- endif %}
{%- endif %}
{%- endfor %}
Expand All @@ -45,9 +45,9 @@ RUN \
ARG CACHEBUST="{{ build_id }}"
{%- endif %}

{%- if module.module_type == "containerfile" %}
{%- if module.module_type.typ() == "containerfile" %}
{%- include "modules/containerfile/containerfile.j2" %}
{%- else if module.module_type == "copy" %}
{%- else if module.module_type.typ() == "copy" %}
{%- include "modules/copy/copy.j2" %}
{%- else %}
RUN \
Expand All @@ -61,10 +61,10 @@ RUN \
{%- else if module.is_local_source() %}
--mount=type=bind,from=stage-modules,src=/modules,dst=/tmp/modules,rw \
{%- else %}
--mount=type=bind,from=ghcr.io/blue-build/modules/{{ module.module_type }}:latest,src=/modules,dst=/tmp/modules,rw \
--mount=type=bind,from={{ blue_build_utils::constants::BLUE_BUILD_MODULE_IMAGE_REF }}/{{ module.module_type.typ() }}:{{ module.module_type.version() }},src=/modules,dst=/tmp/modules,rw \
{%- endif %}
--mount=type=bind,from={{ build_scripts_image }},src=/scripts/,dst=/tmp/scripts/ \
/tmp/scripts/run_module.sh '{{ module.module_type }}' '{{ module|json|safe }}'
/tmp/scripts/run_module.sh '{{ module.module_type.typ() }}' '{{ module|json|safe }}'
{%- endif %}
{%- endif %}
{%- endfor %}
Expand Down
1 change: 1 addition & 0 deletions utils/src/constants.rs
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ pub const XDG_RUNTIME_DIR: &str = "XDG_RUNTIME_DIR";
// Misc
pub const BUILD_SCRIPTS_IMAGE_REF: &str = "ghcr.io/blue-build/cli/build-scripts";
pub const BLUE_BULID_IMAGE_REF: &str = "ghcr.io/blue-build/cli";
pub const BLUE_BUILD_MODULE_IMAGE_REF: &str = "ghcr.io/blue-build/modules";
pub const COSIGN_IMAGE: &str = "ghcr.io/sigstore/cosign/cosign:v2.4.1";
pub const NUSHELL_IMAGE: &str = "ghcr.io/blue-build/nushell-image:latest";
pub const OCI_ARCHIVE: &str = "oci-archive";
Expand Down

0 comments on commit 11b846c

Please sign in to comment.