From 1a371d858df37dfd8772e7922862a37a799dd437 Mon Sep 17 00:00:00 2001 From: Niklas Sombert Date: Fri, 14 Jun 2024 16:18:36 +0200 Subject: [PATCH] Merge xtask run and towbootctl boot-image --- README.md | 12 ++++++++++- towbootctl/Cargo.toml | 3 ++- towbootctl/src/lib.rs | 44 +++++++++++++++++++++++++++++++++++++++ towbootctl/src/main.rs | 44 +-------------------------------------- xtask/Cargo.toml | 2 +- xtask/src/main.rs | 47 +++--------------------------------------- 6 files changed, 62 insertions(+), 90 deletions(-) diff --git a/README.md b/README.md index 3b3866f..9b2a465 100644 --- a/README.md +++ b/README.md @@ -40,6 +40,16 @@ towbootctl install --name yourOS -- -config towboot.toml (You can also configure towboot just with command line arguments instead of using a configuration file; see below.) +### image + +If you're not installing to physical media but instead want to create an image, +towbootctl can do this as well: + +```sh +towbootctl image --target yourOS.img -- -config towboot.toml +towbootctl boot-image --image yourOS.img +``` + ### chainloading from another bootloader If you already have a bootloader capable of loading UEFI applications but @@ -108,7 +118,7 @@ or by setting `--target x86_64_unknown_uefi` (for example). Running `cargo xtask build` will do that and also create a disk image, so just may just want to run this. To boot the resulting image with QEMU, -you can use `cargo xtask run`. +you can use `cargo xtask boot-image`. You can configure whether to create a `debug` or `release` build for either `i686` or `x86_64`, whether to enable KVM or wait for a GDB to attach diff --git a/towbootctl/Cargo.toml b/towbootctl/Cargo.toml index 670a747..6745238 100644 --- a/towbootctl/Cargo.toml +++ b/towbootctl/Cargo.toml @@ -31,7 +31,8 @@ towboot_x64 = { path = "../towboot_x64", optional = true } built = { version = "0.7", features = ["git2"] } [features] -binary = ["argh", "env_logger", "towboot_ia32", "towboot_x64"] +args = ["argh"] +binary = ["args", "env_logger", "towboot_ia32", "towboot_x64"] [[bin]] name = "towbootctl" diff --git a/towbootctl/src/lib.rs b/towbootctl/src/lib.rs index bef9485..bf74dd0 100644 --- a/towbootctl/src/lib.rs +++ b/towbootctl/src/lib.rs @@ -1,10 +1,13 @@ //! This crate offers functionality to use towboot for your own operating system. +#![cfg_attr(feature = "args", feature(exit_status_error))] use std::fs::OpenOptions; use std::io::Write; use std::path::{Path, PathBuf}; use std::process::Command; use anyhow::{anyhow, Result}; +#[cfg(feature = "args")] +use argh::FromArgs; use log::info; use tempfile::{NamedTempFile, TempPath}; @@ -155,3 +158,44 @@ pub fn boot_image( }) } +#[cfg(feature = "args")] +#[derive(Debug, FromArgs)] +#[argh(subcommand, name = "boot-image")] +/// Boot an image. +pub struct BootImageCommand { + /// what image to boot + #[argh(option, default = "PathBuf::from(\"image.img\")")] + image: PathBuf, + + /// use x86_64 instead of i686 + #[argh(switch)] + x86_64: bool, + + /// enable KVM + #[argh(switch)] + kvm: bool, + + /// use Bochs instead of QEMU + #[argh(switch)] + bochs: bool, + + /// wait for GDB to attach + #[argh(switch)] + gdb: bool, + + /// use the specified firmware instead of OVMF + #[argh(option)] + firmware: Option, +} + +#[cfg(feature = "args")] +impl BootImageCommand { + pub fn r#do(&self) -> Result<()> { + let (mut process, _temp_files) = boot_image( + self.firmware.as_deref(), &self.image, self.x86_64, self.bochs, + self.kvm, self.gdb, + )?; + process.status()?.exit_ok()?; + Ok(()) + } +} diff --git a/towbootctl/src/main.rs b/towbootctl/src/main.rs index 7933493..0cecfc1 100644 --- a/towbootctl/src/main.rs +++ b/towbootctl/src/main.rs @@ -1,5 +1,4 @@ //! A companion utility for towboot. -#![feature(exit_status_error)] use std::fs; use std::env; use std::io::Write; @@ -10,7 +9,7 @@ use anyhow::Result; use log::info; use tempfile::NamedTempFile; -use towbootctl::{boot_image, create_image, config, runtime_args_to_load_options}; +use towbootctl::{BootImageCommand, create_image, config, runtime_args_to_load_options}; #[allow(dead_code)] mod built_info { @@ -33,47 +32,6 @@ enum Command { Version(VersionCommand), } -// TODO: dedup this with xtask's run -#[derive(Debug, FromArgs)] -#[argh(subcommand, name = "boot-image")] -/// Boot an image. -struct BootImageCommand { - /// what image to boot - #[argh(option, default = "PathBuf::from(\"image.img\")")] - image: PathBuf, - - /// use x86_64 instead of i686 - #[argh(switch)] - x86_64: bool, - - /// enable KVM - #[argh(switch)] - kvm: bool, - - /// use Bochs instead of QEMU - #[argh(switch)] - bochs: bool, - - /// wait for GDB to attach - #[argh(switch)] - gdb: bool, - - /// use the specified firmware instead of OVMF - #[argh(option)] - firmware: Option, -} - -impl BootImageCommand { - fn r#do(&self) -> Result<()> { - let (mut process, _temp_files) = boot_image( - self.firmware.as_deref(), &self.image, self.x86_64, self.bochs, - self.kvm, self.gdb, - )?; - process.status()?.exit_ok()?; - Ok(()) - } -} - #[derive(Debug, FromArgs)] #[argh(subcommand, name = "image")] /// Build a bootable image containing towboot, kernels and their modules. diff --git a/xtask/Cargo.toml b/xtask/Cargo.toml index eff5f3f..8aab49c 100644 --- a/xtask/Cargo.toml +++ b/xtask/Cargo.toml @@ -15,4 +15,4 @@ env_logger = { version = "0.11", default-features = false, features = ["auto-col anyhow = "1.0" thiserror = "1.0" -towbootctl = { path = "../towbootctl" } +towbootctl = { path = "../towbootctl", features = ["args"] } diff --git a/xtask/src/main.rs b/xtask/src/main.rs index 772e3b2..301e3b5 100644 --- a/xtask/src/main.rs +++ b/xtask/src/main.rs @@ -7,7 +7,7 @@ use anyhow::Result; use argh::{FromArgs, from_env}; use log::info; -use towbootctl::{boot_image, create_image}; +use towbootctl::{BootImageCommand, create_image}; #[derive(Debug, FromArgs)] /// Top-level command. @@ -20,7 +20,7 @@ struct Cli { #[argh(subcommand)] enum Command { Build(Build), - Run(Run), + BootImage(BootImageCommand), } #[derive(Debug, FromArgs)] @@ -87,47 +87,6 @@ impl Build { } } -#[derive(Debug, FromArgs)] -#[argh(subcommand, name = "run")] -/// Run an image in a VM -struct Run { - /// what image to boot - #[argh(option, default = "PathBuf::from(\"image.img\")")] - image: PathBuf, - - /// use x86_64 instead of i686 - #[argh(switch)] - x86_64: bool, - - /// enable KVM - #[argh(switch)] - kvm: bool, - - /// use Bochs instead of QEMU - #[argh(switch)] - bochs: bool, - - /// wait for GDB to attach - #[argh(switch)] - gdb: bool, - - /// use the specified firmware instead of OVMF - #[argh(option)] - firmware: Option, -} - - -impl Run { - fn r#do(self) -> Result<()> { - let (mut process, _temp_files) = boot_image( - self.firmware.as_deref(), &self.image, self.x86_64, self.bochs, - self.kvm, self.gdb, - )?; - process.status()?.exit_ok()?; - Ok(()) - } -} - /// This gets started from the command line. fn main() -> Result<()> { if env::var("RUST_LOG").is_err() { @@ -137,6 +96,6 @@ fn main() -> Result<()> { let args: Cli = from_env(); match args.command { Command::Build(build) => build.r#do(), - Command::Run(run) => run.r#do(), + Command::BootImage(boot_image) => boot_image.r#do(), } }