Skip to content

Commit

Permalink
slight refactoring
Browse files Browse the repository at this point in the history
  • Loading branch information
korewaChino committed Oct 10, 2023
1 parent 14732c9 commit 7c0c056
Show file tree
Hide file tree
Showing 8 changed files with 98 additions and 780 deletions.
6 changes: 3 additions & 3 deletions .github/workflows/build-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ jobs:
- name: Upload artifacts
uses: actions/upload-artifact@v3
with:
name: katsudon
name: image-arm
path: tests/ng/katsu-work/image/*.img.xz

image-x86_64:
Expand Down Expand Up @@ -131,7 +131,7 @@ jobs:
- name: Upload artifacts
uses: actions/upload-artifact@v3
with:
name: katsudon
name: image-x86_64
path: tests/ng/katsu-work/image/*.raw.xz


Expand Down Expand Up @@ -182,5 +182,5 @@ jobs:
- name: Upload artifacts
uses: actions/upload-artifact@v3
with:
name: katsudon
name: iso-x86_64
path: tests/ng/katsu-work/image/*.iso.xz
49 changes: 36 additions & 13 deletions src/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ use crate::{
cli::OutputFormat,
config::{Manifest, Script},
};
use cmd_lib::{run_cmd, run_fun};
use color_eyre::{eyre::eyre, Result};
use serde_derive::{Deserialize, Serialize};
use std::{
Expand All @@ -14,11 +15,10 @@ use std::{
use tracing::{debug, info, trace, warn};

const WORKDIR: &str = "katsu-work";
const VOLID: &str = "KATSU-LIVEOS";
crate::prepend_comment!(GRUB_PREPEND_COMMENT: "/etc/default/grub", "Grub default configurations", katsu::builder::Bootloader::cp_grub);
crate::prepend_comment!(LIMINE_PREPEND_COMMENT: "/boot/limine.cfg", "Limine configurations", katsu::builder::Bootloader::cp_limine);

#[derive(Default)]
#[derive(Default, Debug, Clone, Serialize, Deserialize)]
pub enum Bootloader {
#[default]
Grub,
Expand Down Expand Up @@ -97,6 +97,7 @@ impl Bootloader {

fn cp_limine(&self, manifest: &Manifest, chroot: &Path) -> Result<()> {
// complaint to rust: why can't you coerce automatically with umwrap_or()????
info!("Copying Limine files");
let distro = &manifest.distro.as_ref().map_or("Linux", |s| s);
let cmd = &manifest.kernel_cmdline.as_ref().map_or("", |s| s);
let root = chroot.parent().unwrap().join(ISO_TREE);
Expand All @@ -113,33 +114,51 @@ impl Bootloader {
std::fs::copy("/usr/share/limine/limine-bios.sys", root.join("boot/limine-bios.sys"))?;

let (vmlinuz, initramfs) = self.cp_vmlinuz_initramfs(chroot, &root)?;
let volid = manifest.get_volid();

// Generate limine.cfg
let mut f = std::fs::File::create(root.join("boot/limine.cfg"))
let limine_cfg = root.join("boot/limine.cfg");
let mut f = std::fs::File::create(&limine_cfg)
.map_err(|e| eyre!(e).wrap_err("Cannot create limine.cfg"))?;

f.write_all(LIMINE_PREPEND_COMMENT.as_bytes())?;
f.write_fmt(format_args!("TIMEOUT=5\n\n:{distro}\n\tPROTOCOL=linux\n\t"))?;
f.write_fmt(format_args!("KERNEL_PATH=boot:///boot/{vmlinuz}\n\t"))?;
f.write_fmt(format_args!("MODULE_PATH=boot:///boot/{initramfs}\n\t"))?;
f.write_fmt(format_args!(
"CMDLINE=root=live:LABEL={VOLID} rd.live.image enforcing=0 {cmd}"
"CMDLINE=root=live:LABEL={volid} rd.live.image enforcing=0 {cmd}"
))?;

let binding = run_fun!(b2sum $limine_cfg)?;
let liminecfg_b2h = binding.split_whitespace().next().unwrap();

// enroll limine secure boot

info!("Enrolling Limine Secure Boot");

tracing::info_span!("Enrolling Limine Secure Boot").in_scope(|| -> Result<()> {
Ok(run_cmd!(
limine enroll-config $root/boot/limine-uefi-cd.bin $liminecfg_b2h 2>&1;
limine enroll-config $root/boot/limine-bios.sys $liminecfg_b2h 2>&1;
)?)
})?;

Ok(())
}

fn cp_grub(&self, manifest: &Manifest, chroot: &Path) -> Result<()> {
let imgd = chroot.parent().unwrap().join("image/");
let imgd = chroot.parent().unwrap().join(ISO_TREE);
let cmd = &manifest.kernel_cmdline.as_ref().map_or("", |s| s);
let volid = manifest.get_volid();

let cfg = std::fs::read_to_string(chroot.join("etc/default/grub"))?;
fs::create_dir_all(imgd.join("etc/default"))?;
let mut f = std::fs::File::create(chroot.join("etc/default/grub"))?;
let cfg = std::fs::read_to_string(chroot.join("etc/default/grub"))?;
f.write_all(GRUB_PREPEND_COMMENT.as_bytes())?;
for l in cfg.lines() {
if l.starts_with("GRUB_CMDLINE_LINUX=") {
f.write_fmt(format_args!(
"GRUB_CMDLINE_LINUX=\"root=live:LABEL={VOLID} rd.live.image selinux=0 {cmd}\"\n"
"GRUB_CMDLINE_LINUX=\"root=live:LABEL={volid} rd.live.image enforcing=0 {cmd}\"\n"
))?;
} else {
f.write_all(l.as_bytes())?;
Expand Down Expand Up @@ -470,11 +489,12 @@ impl IsoBuilder {
cmd_lib::run_cmd!(mkfs.erofs -d $chroot -o $image)?;
Ok(())
}
pub fn xorriso(&self, chroot: &Path, image: &Path) -> Result<()> {
pub fn xorriso(&self, chroot: &Path, image: &Path, manifest: &Manifest) -> Result<()> {
let volid = manifest.get_volid();
let (uefi_bin, bios_bin) = self.bootloader.get_bins();
let root = chroot.parent().unwrap().join(ISO_TREE);
debug!("xorriso -as mkisofs -b {bios_bin} -no-emul-boot -boot-load-size 4 -boot-info-table --efi-boot {uefi_bin} -efi-boot-part --efi-boot-image --protective-msdos-label {root} -volid KATSU-LIVEOS -o {image}", bios_bin = bios_bin, uefi_bin = uefi_bin, root = root.display(), image = image.display());
cmd_lib::run_cmd!(xorriso -as mkisofs -b $bios_bin -no-emul-boot -boot-load-size 4 -boot-info-table --efi-boot $uefi_bin -efi-boot-part --efi-boot-image --protective-msdos-label $root -volid $VOLID -o $image 2>&1)?;
cmd_lib::run_cmd!(xorriso -as mkisofs -b $bios_bin -no-emul-boot -boot-load-size 4 -boot-info-table --efi-boot $uefi_bin -efi-boot-part --efi-boot-image --protective-msdos-label $root -volid $volid -o $image 2>&1)?;
Ok(())
}
}
Expand All @@ -483,6 +503,8 @@ const ISO_TREE: &str = "iso-tree";

impl ImageBuilder for IsoBuilder {
fn build(&self, chroot: &Path, image: &Path, manifest: &Manifest) -> Result<()> {
// let iso_config = manifest.iso.as_ref().expect("A valid ISO configuration");

// Create workspace directory
let workspace = chroot.parent().unwrap().to_path_buf();
debug!("Workspace: {workspace:#?}");
Expand All @@ -506,7 +528,7 @@ impl ImageBuilder for IsoBuilder {
let image = format!("{}/katsu.iso", image.display());
let path = PathBuf::from(image);

self.xorriso(chroot, path.as_path())?;
self.xorriso(chroot, path.as_path(), manifest)?;
self.bootloader.install(path.as_path())?;

Ok(())
Expand All @@ -527,13 +549,14 @@ impl KatsuBuilder {
_ => todo!("builder not implemented"),
};

let bootloader = manifest.bootloader.clone();

let image_builder = match output_format {
OutputFormat::Iso => {
Box::new(IsoBuilder { bootloader: Bootloader::Limine, root_builder })
as Box<dyn ImageBuilder>
Box::new(IsoBuilder { bootloader, root_builder }) as Box<dyn ImageBuilder>
},
OutputFormat::DiskImage => Box::new(DiskImageBuilder {
bootloader: Bootloader::Limine,
bootloader,
root_builder,
image: PathBuf::from("./katsu-work/image/katsu.img"),
}) as Box<dyn ImageBuilder>,
Expand Down
101 changes: 0 additions & 101 deletions src/cfg.rs

This file was deleted.

50 changes: 48 additions & 2 deletions src/config.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,34 @@
use crate::chroot_run_cmd;
use crate::{builder::Bootloader, chroot_run_cmd};
use bytesize::ByteSize;
use color_eyre::Result;
use merge_struct::merge;
use serde_derive::{Deserialize, Serialize};
use serde::Deserialize;
use serde_derive::Serialize;
use std::{
collections::BTreeMap,
fs,
io::Write,
path::{Path, PathBuf},
};
use tracing::{debug, info, trace};
const DEFAULT_VOLID: &str = "KATSU-LIVEOS";

#[derive(Deserialize, Debug, Clone, Serialize)]
pub struct IsoConfig {
/// Volume ID for the ISO image
#[serde(default)]
pub volume_id: Option<String>,
}

impl IsoConfig {
pub fn get_volid(&self) -> String {
if let Some(volid) = &self.volume_id {
volid.clone()
} else {
DEFAULT_VOLID.to_string()
}
}
}

#[derive(Deserialize, Debug, Clone, Serialize)]
pub struct Manifest {
Expand All @@ -31,6 +50,7 @@ pub struct Manifest {

/// DNF configuration
// todo: dynamically load this?
#[serde(default)]
pub dnf: crate::builder::DnfRootBuilder,

/// Scripts to run before and after the build
Expand All @@ -43,9 +63,35 @@ pub struct Manifest {

/// Extra parameters to the kernel command line in bootloader configs
pub kernel_cmdline: Option<String>,

/// ISO config (optional)
/// This is only used for ISO images
#[serde(default)]
pub iso: Option<IsoConfig>,

// deserialize with From<&str>
#[serde(default, deserialize_with = "deseralize_bootloader")]
pub bootloader: Bootloader,
}

// Function to deserialize String into Bootloader

fn deseralize_bootloader<'de, D>(deserializer: D) -> Result<Bootloader, D::Error>
where
D: serde::Deserializer<'de>,
{
let s = String::deserialize(deserializer)?;
Ok(Bootloader::from(s.as_str()))
}

impl Manifest {
pub fn get_volid(&self) -> String {
if let Some(iso) = &self.iso {
iso.get_volid()
} else {
DEFAULT_VOLID.to_string()
}
}
/// Loads a single manifest from a file
pub fn load(path: &Path) -> Result<Self> {
let mut manifest: Self = serde_yaml::from_str(&std::fs::read_to_string(path)?)?;
Expand Down
Loading

0 comments on commit 7c0c056

Please sign in to comment.