feat: Allow use of akmods module (#71)
The akmods module require having the /rpms directory put into /tmp/rpms.
By default we will mount the akmods image with the `main-{{ os_version
}}` tag.
If a user supplies `base` for the akmods module in their recipe, it will
pull that image tag instead and mount the resulting /rpms.
```yaml
modules:
- type: akmods
base: surface
install:
- openrazer
```
This would pull the image `ghcr.io/ublue-os/akmods:surface-39`.
A user can also supply `nvidia-version` with the numerical version of
the driver you would like to use. Doing so will mount the appropriate
`akmods-nvidia` image with the version of the driver you want in the
tag.
```yaml
modules:
- type: akmods
nvidia-version: 545
install:
- nvidia
```
This would pull the image `ghcr.io/ublue-os/akmods-nvidia:main-39-545`
and `ghcr.io/ublue-os/akmods:main-39`.
This uses bind mount like all the other modules so these files will not
persist into the final image.
This commit is contained in:
parent
ee2a834b28
commit
8931a22e29
4 changed files with 88 additions and 14 deletions
|
|
@ -4,12 +4,21 @@ name: template
|
|||
description: This is my personal OS image.
|
||||
|
||||
# the base image to build on top of (FROM) and the version tag to use
|
||||
base-image: ghcr.io/ublue-os/silverblue-main
|
||||
base-image: ghcr.io/ublue-os/silverblue-surface
|
||||
image-version: 39 # latest is also supported if you want new updates ASAP
|
||||
|
||||
# module configuration, executed in order
|
||||
# you can include multiple instances of the same module
|
||||
modules:
|
||||
- type: akmods
|
||||
base: surface
|
||||
nvidia-version: 545
|
||||
install:
|
||||
- nvidia
|
||||
- openrazer
|
||||
- type: akmods
|
||||
install:
|
||||
- openrgb
|
||||
- type: files
|
||||
files:
|
||||
- usr: /usr # copies config/files/usr into your image's /usr.
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
use std::{
|
||||
collections::HashSet,
|
||||
env, fs,
|
||||
path::{Path, PathBuf},
|
||||
process,
|
||||
|
|
@ -13,7 +14,7 @@ use uuid::Uuid;
|
|||
|
||||
use crate::{
|
||||
constants::*,
|
||||
module_recipe::{Module, Recipe},
|
||||
module_recipe::{Module, ModuleExt, Recipe},
|
||||
};
|
||||
|
||||
use super::BlueBuildCommand;
|
||||
|
|
@ -166,7 +167,7 @@ fn get_containerfile_snippets(module: &Module) -> Option<Vec<String>> {
|
|||
|
||||
#[must_use]
|
||||
fn print_containerfile(containerfile: &str) -> String {
|
||||
debug!("print_containerfile({containerfile})");
|
||||
trace!("print_containerfile({containerfile})");
|
||||
debug!("Loading containerfile contents for {containerfile}");
|
||||
|
||||
let path = format!("config/containerfiles/{containerfile}/Containerfile");
|
||||
|
|
@ -222,3 +223,56 @@ fn get_gitlab_registry_path() -> Option<String> {
|
|||
.to_lowercase(),
|
||||
)
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, TypedBuilder, PartialEq, Eq, Hash)]
|
||||
struct AkmodsInfo {
|
||||
images: (String, Option<String>),
|
||||
stage_name: String,
|
||||
}
|
||||
|
||||
fn get_akmods_info_list(module_ext: &ModuleExt, os_version: &str) -> Vec<AkmodsInfo> {
|
||||
trace!("get_akmods_image_list({module_ext:#?}, {os_version})");
|
||||
|
||||
let mut seen = HashSet::new();
|
||||
|
||||
module_ext
|
||||
.modules
|
||||
.iter()
|
||||
.filter(|module| module.module_type.as_ref().is_some_and(|t| t == "akmods"))
|
||||
.map(|module| generate_akmods_info(module, os_version))
|
||||
.filter(|image| seen.insert(image.clone()))
|
||||
.collect()
|
||||
}
|
||||
|
||||
fn generate_akmods_info(module: &Module, os_version: &str) -> AkmodsInfo {
|
||||
trace!("generate_akmods_base({module:#?}, {os_version})");
|
||||
|
||||
let base = module
|
||||
.config
|
||||
.get("base")
|
||||
.map(|b| b.as_str().unwrap_or_default());
|
||||
let nvidia_version = module
|
||||
.config
|
||||
.get("nvidia-version")
|
||||
.map(|v| v.as_u64().unwrap_or_default());
|
||||
|
||||
AkmodsInfo::builder()
|
||||
.images(match (base, nvidia_version) {
|
||||
(Some(b), Some(nv)) if !b.is_empty() && nv > 0 => (
|
||||
format!("akmods:{b}-{os_version}"),
|
||||
Some(format!("akmods-nvidia:{b}-{os_version}-{nv}")),
|
||||
),
|
||||
(Some(b), _) if !b.is_empty() => (format!("akmods:{b}-{os_version}"), None),
|
||||
(_, Some(nv)) if nv > 0 => (
|
||||
format!("akmods:main-{os_version}"),
|
||||
Some(format!("akmods-nvidia:main-{os_version}")),
|
||||
),
|
||||
_ => (format!("akmods:main-{os_version}"), None),
|
||||
})
|
||||
.stage_name(format!(
|
||||
"{}{}",
|
||||
base.unwrap_or("main"),
|
||||
nvidia_version.map_or_else(String::default, |nv| format!("-{nv}"))
|
||||
))
|
||||
.build()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -153,7 +153,7 @@ impl<'a> Recipe<'a> {
|
|||
Ok(recipe)
|
||||
}
|
||||
|
||||
fn get_os_version(&self) -> String {
|
||||
pub fn get_os_version(&self) -> String {
|
||||
trace!("Recipe::get_os_version()");
|
||||
|
||||
if check_command_exists("skopeo").is_err() {
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
{%- let os_version = recipe.get_os_version() %}
|
||||
# This stage is responsible for holding onto
|
||||
# your config without copying it directly into
|
||||
# the final image
|
||||
|
|
@ -11,6 +12,14 @@ FROM scratch as stage-modules
|
|||
COPY --from=ghcr.io/ublue-os/bling:latest /modules /modules
|
||||
COPY ./modules /modules
|
||||
|
||||
{%- for info in self::get_akmods_info_list(recipe.modules_ext, os_version) %}
|
||||
FROM scratch as stage-akmods-{{ info.stage_name }}
|
||||
COPY --from=ghcr.io/ublue-os/{{ info.images.0 }} /rpms /rpms
|
||||
{%- if let Some(nv_image) = info.images.1 %}
|
||||
COPY --from=ghcr.io/ublue-os/{{ nv_image }} /rpms /rpms
|
||||
{%- endif %}
|
||||
{%- endfor %}
|
||||
|
||||
# This stage is responsible for holding onto
|
||||
# exports like the exports.sh
|
||||
FROM docker.io/alpine as stage-exports
|
||||
|
|
@ -37,16 +46,6 @@ ARG IMAGE_REGISTRY=localhost
|
|||
COPY cosign.pub /usr/share/ublue-os/cosign.pub
|
||||
{%- endif %}
|
||||
|
||||
COPY --from=docker.io/mikefarah/yq /usr/bin/yq /usr/bin/yq
|
||||
COPY --from=gcr.io/projectsigstore/cosign /ko-app/cosign /usr/bin/cosign
|
||||
|
||||
COPY --from=ghcr.io/blue-build/cli:
|
||||
{%- if let Some(tag) = recipe.blue_build_tag -%}
|
||||
{{ tag }}
|
||||
{%- else -%}
|
||||
latest-installer
|
||||
{%- endif %} /out/bluebuild /usr/bin/bluebuild
|
||||
|
||||
ARG CONFIG_DIRECTORY="/tmp/config"
|
||||
ARG IMAGE_NAME="{{ recipe.name }}"
|
||||
ARG BASE_IMAGE="{{ recipe.base_image }}"
|
||||
|
|
@ -74,12 +73,16 @@ COPY {{ src }} {{ dest }}
|
|||
RUN \
|
||||
--mount=type=tmpfs,target=/tmp \
|
||||
--mount=type=tmpfs,target=/var \
|
||||
--mount=type=bind,from=docker.io/mikefarah/yq,src=/usr/bin/yq,dst=/usr/bin/yq \
|
||||
--mount=type=bind,from=stage-config,src=/config,dst=/tmp/config,rw \
|
||||
{%- if let Some(source) = module.source %}
|
||||
--mount=type=bind,from={{ source }},src=/modules,dst=/tmp/modules,rw \
|
||||
{%- else %}
|
||||
--mount=type=bind,from=stage-modules,src=/modules,dst=/tmp/modules,rw \
|
||||
{%- endif %}
|
||||
{%- if type == "akmods" %}
|
||||
--mount=type=bind,from=stage-akmods-{{ self::generate_akmods_info(module, os_version).stage_name }},src=/rpms,dst=/tmp/rpms,rw \
|
||||
{%- endif %}
|
||||
--mount=type=bind,from=stage-exports,src=/exports.sh,dst=/tmp/exports.sh \
|
||||
--mount=type=cache,dst=/var/cache/rpm-ostree,id=rpm-ostree-cache-{{ recipe.name }}-{{ recipe.image_version }},sharing=locked \
|
||||
chmod +x /tmp/modules/{{ type }}/{{ type }}.sh \
|
||||
|
|
@ -88,4 +91,12 @@ RUN \
|
|||
{%- endif %}
|
||||
{%- endfor %}
|
||||
|
||||
COPY --from=gcr.io/projectsigstore/cosign /ko-app/cosign /usr/bin/cosign
|
||||
COPY --from=ghcr.io/blue-build/cli:
|
||||
{%- if let Some(tag) = recipe.blue_build_tag -%}
|
||||
{{ tag }}
|
||||
{%- else -%}
|
||||
latest-installer
|
||||
{%- endif %} /out/bluebuild /usr/bin/bluebuild
|
||||
|
||||
RUN ostree container commit
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue