Skip to content

Commit

Permalink
feat: more cfgs
Browse files Browse the repository at this point in the history
  • Loading branch information
madonuko committed Sep 19, 2023
1 parent 2af9185 commit dd0dbaf
Show file tree
Hide file tree
Showing 8 changed files with 52 additions and 178 deletions.
133 changes: 0 additions & 133 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,134 +1 @@
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class

# C extensions
*.so

# Distribution / packaging
.Python
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
pip-wheel-metadata/
share/python-wheels/
*.egg-info/
.installed.cfg
*.egg
MANIFEST

# PyInstaller
# Usually these files are written by a python script from a template
# before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec

# Installer logs
pip-log.txt
pip-delete-this-directory.txt

# Unit test / coverage reports
htmlcov/
.tox/
.nox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*.cover
*.py,cover
.hypothesis/
.pytest_cache/

# Translations
*.mo
*.pot

# Django stuff:
*.log
local_settings.py
db.sqlite3
db.sqlite3-journal

# Flask stuff:
instance/
.webassets-cache

# Scrapy stuff:
.scrapy

# Sphinx documentation
docs/_build/

# PyBuilder
target/

# Jupyter Notebook
.ipynb_checkpoints

# IPython
profile_default/
ipython_config.py

# pyenv
.python-version

# pipenv
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
# However, in case of collaboration, if having platform-specific dependencies or dependencies
# having no cross-platform support, pipenv may install dependencies that don't work, or not
# install all needed dependencies.
#Pipfile.lock

# PEP 582; used by e.g. github.com/David-OConnor/pyflow
__pypackages__/

# Celery stuff
celerybeat-schedule
celerybeat.pid

# SageMath parsed files
*.sage.py

# Environments
.env
.venv
env/
venv/
ENV/
env.bak/
venv.bak/

# Spyder project settings
.spyderproject
.spyproject

# Rope project settings
.ropeproject

# mkdocs documentation
/site

# mypy
.mypy_cache/
.dmypy.json
dmypy.json

# Pyre type checker
.pyre/


# Added by cargo

/target
7 changes: 4 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
# katsu
An experimental image builder
An experimental image builder for RPM/DNF based systems.

## Dependencies
- `xorriso`
- `dracut`
- `gurb2`
- `syslinux-nonlinux`
- `limine` or `grub2`
- `rpm`
- `dnf` or `dnf5`
10 changes: 10 additions & 0 deletions src/cfg.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,16 @@ pub struct System {
pub releasever: u8,
/// The root password of the new system.
pub rootpw: SStr,
/// The bootloader to install.
/// - `limine` (default)
/// - `grub`
pub bootloader: Option<String>,
/// More kernel parameters.
/// By default the kernel parameters are:
/// `root=live:LABEL={volid} rd.live.image selinux=0`
///
/// If you want to add more parameters after the default ones, use this option.
pub kernel_params: Option<String>,
}

#[derive(Deserialize, Debug)]
Expand Down
63 changes: 32 additions & 31 deletions src/creator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use tracing::{debug, error, info, instrument, trace, warn};
use crate::{cfg::Config, run};

const DEFAULT_DNF: &str = "dnf5";
const DEFAULT_BOOTLOADER: &str = "limine";

pub trait LiveImageCreator {
/// src, dest, required
Expand All @@ -26,7 +27,7 @@ pub trait LiveImageCreator {
}

fn dracut(&self) -> Result<()> {
self.fstab()?;
// self.fstab()?;
let cfg = self.get_cfg();
let root = cfg.instroot.canonicalize().expect("Cannot canonicalize instroot.");
let root = root.to_str().unwrap();
Expand Down Expand Up @@ -103,30 +104,41 @@ pub trait LiveImageCreator {
self.init_script()?;
self.instpkgs()?;
self.dracut()?;
let cfg = self.get_cfg();
// self.copy_efi_files(&cfg.instroot)?;
self.rootpw()?;
self.postinst_script()?;
self.squashfs()?;
self.liveos()?;
self.xorriso()?;
self.bootloader()?;
let cfg = self.get_cfg();
info!("Done: {}.iso", cfg.out);
Ok(())
}

fn bootloader(&self) -> Result<()> {
match self.get_cfg().sys.bootloader.as_ref().map(|x| x.as_str()).unwrap_or(DEFAULT_BOOTLOADER) {
"limine" => self.limine(),
"grub" => self.grub(),
x => Err(eyre!("Unknown bootloader: {x}")),
}
}
fn limine(&self) -> Result<()> {
info!("Installing Limine bootloader");
let out = &self.get_cfg().out;
run!("limine", "bios-install", &*format!("{out}.iso"))?;
Ok(())
}
fn grub(&self) -> Result<()> {
info!("Installing GRUB bootloader");
// let out = &self.get_cfg().out;
// self.copy_efi_files(instroot)
unimplemented!()
}

/// Returns volid
fn liveos(&self) -> Result<()> {
let cfg = self.get_cfg();
let distro = &cfg.distro;
let out = &cfg.out;
std::fs::create_dir_all(format!("./{distro}/LiveOS"))?;
std::fs::copy(
"/usr/share/limine/limine-uefi-cd.bin",
Expand All @@ -141,8 +153,6 @@ pub trait LiveImageCreator {
format!("./{distro}/boot/limine-bios.sys"),
)?;
self.limine_cfg(&*format!("./{distro}/boot/limine.cfg"), distro)?;

std::fs::rename(format!("{out}.img"), format!("./{distro}/LiveOS/squashfs.img"))?;
Ok(())
}

Expand All @@ -152,13 +162,14 @@ pub trait LiveImageCreator {
let kver = &Self::get_krnl_ver(root.to_str().unwrap())?;
let kver = kver.trim_start_matches("kernel-");
let volid = &cfg.volid;
let cmdline = cfg.sys.kernel_params.as_ref().map(String::as_str).unwrap_or_default();
let mut f = std::fs::File::create(path)
.map_err(|e| eyre!(e).wrap_err("Cannot create limine.cfg"))?;

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-{kver}\n\t"))?;
f.write_fmt(format_args!("MODULE_PATH=boot:///boot/initramfs-{kver}.img\n\t"))?;
f.write_fmt(format_args!("CMDLINE=root=live:LABEL={volid} rd.live.image selinux=0"))?; // maybe enforcing=0
f.write_fmt(format_args!("CMDLINE=root=live:LABEL={volid} rd.live.image selinux=0 {cmdline}"))?; // maybe enforcing=0
Ok(())
}

Expand Down Expand Up @@ -231,30 +242,15 @@ pub trait LiveImageCreator {
debug!(?script, ?dest, "Copying postinst script");
std::fs::copy(script, &dest)?;
debug!("Mounting /dev, /proc, /sys");
// cmd_lib::run_cmd! (
// mount -t proc proc $rootname/proc;
// mount -t sysfs sys $rootname/sys;
// mount -o bind /dev $rootname/dev;
// mount -o bind /dev $rootname/dev/pts;
// sh -c "mv $rootname/etc/resolv.conf $rootname/etc/resolv.conf.bak || true";
// cp /etc/resolv.conf $rootname/etc/resolv.conf;
// )?;
// prepare_chroot(rootname)?;
prepare_chroot(rootname)?;
info!(?script, "Running postinst script");
// TODO: use unshare
run!(~"chroot", &rootname, &*format!("/{name}"))
.map_err(|e| e.wrap_err("postinst script failed"))?;
debug!(?dest, "Removing postinst script");
std::fs::remove_file(dest)?;
debug!("Unmounting /dev, /proc, /sys");
// cmd_lib::run_cmd! (
// umount $rootname/dev/pts;
// umount $rootname/dev;
// umount $rootname/sys;
// umount $rootname/proc;
// sh -c "mv $rootname/etc/resolv.conf.bak $rootname/etc/resolv.conf || true";
// )?;
// unmount_chroot(rootname)?;
unmount_chroot(rootname)?;
Ok(())
}
Expand All @@ -273,11 +269,11 @@ pub trait LiveImageCreator {
fn squashfs(&self) -> Result<()> {
let cfg = self.get_cfg();
let name = format!("{}.img", cfg.out);
let distro = &cfg.distro;
let name = format!("./{distro}/LiveOS/squashfs.img");
let root = &cfg.instroot.canonicalize().expect("Cannot canonicalize instroot.");
let root = root.to_str().unwrap();
let instroot = &cfg.instroot;
let distro = &cfg.distro;
cmd_lib::run_cmd!(
mkdir -p $distro/boot;
Expand All @@ -286,7 +282,7 @@ pub trait LiveImageCreator {
info!(name, root, "Squashing fs");
run!(~"mksquashfs", root, &name, "-comp", "gzip", "-noappend")?;
run!(~"mksquashfs", root, &name, "-comp", "xz", "-noappend", "-Xdict-size", "100%", "-b", "1048576")?;
Ok(())
}
Expand Down Expand Up @@ -316,7 +312,6 @@ pub trait LiveImageCreator {
if instroot.is_dir() {
debug!("Using preexisting dir as instroot: {instroot:?}");
if let Some(Ok(_)) = std::fs::read_dir(instroot)?.next() {
// return Err(eyre!("{instroot:?} is not empty."));
warn!("{instroot:?} is not empty.");
}
} else {
Expand All @@ -325,6 +320,8 @@ pub trait LiveImageCreator {
}
std::fs::create_dir(instroot)?;
}
trace!("Checking for ISO directory");
std::fs::create_dir_all(format!("./{}/LiveOS", cfg.distro))?;
Ok(())
}
Expand All @@ -337,9 +334,13 @@ pub trait LiveImageCreator {
let root = &cfg.instroot.canonicalize().expect("Cannot canonicalize instroot.");
let root = root.to_str().unwrap();
let pkgs: Vec<&str> = cfg.packages.iter().map(|x| x.as_str()).collect();
// prepare_chroot(root)?;
cmd_lib::run_cmd!($dnf in -y --releasever=$rel --installroot $root $[pkgs])?;
// unmount_chroot(root)?;
// if dnf == "dnf5" {
// pkgs.push("--use-host-config");
// }
cmd_lib::run_cmd!(
$dnf in -y --releasever=$rel --installroot $root $[pkgs];
$dnf clean all;
)?;
Ok(())
}
}
Expand Down
3 changes: 3 additions & 0 deletions tests/.env
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# KATSU_TABEN=trace
KATSU_TABEN=info
RUST_BACKTRACE=full
2 changes: 2 additions & 0 deletions tests/.gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
instroot/
Ultramarine-Linux
out.iso
10 changes: 0 additions & 10 deletions tests/katsudon-test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,6 @@ out: out
volid: ULTRAMARINE
packages:
# dracut stuff below
# - keyutils
# - busybox
# - rng-tools
- filesystem
- setup
- lvm2
Expand All @@ -17,14 +14,7 @@ packages:
- nvme-cli
- biosdevname
- dracut-live
# - wicked
# - nbd
# - iscsi-initiator-utils
# - cifs-utils
# - fcoe-utils
- dbus-daemon
# - rpcbind
# - nfs-utils
# necessary stuff
- "@core"
- fedora-repos
Expand Down
2 changes: 1 addition & 1 deletion tests/postinst.sh
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,4 @@ echo "Fixing SELinux labels"

fixfiles -Ra restore

# dnf5 up -y # for downloading keys
dnf5 up -y # for downloading keys

0 comments on commit dd0dbaf

Please sign in to comment.