Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

quark: Implement run command #6

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,6 @@ Cargo.lock
.idea
*.tar.gz
.vscode
ctr-bundle
ctr-bundle
quardle*
lumper*
9 changes: 8 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,11 @@ edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
clap = { version = "3.0.5", features = ["derive"] }
clap = { version = "3.0.5", features = ["derive"] }
execute = "0.2.10"
flate2 = "1.0.22"
tar = "0.4.38"
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
log = { version = "0.4", features = ["std", "serde"] }
env_logger = "0.9.0"
2 changes: 1 addition & 1 deletion src/cli/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ pub struct BuildCommand {

/// Method that will be called when the command is executed.
impl Handler for BuildCommand {
fn handler(&self) -> Result<()> {
fn handler(&self, _logger: &mut env_logger::Builder) -> Result<()> {
Ok(())
}
}
7 changes: 6 additions & 1 deletion src/cli/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,18 @@ impl From<std::io::Error> for Error {
pub type Result<T> = std::result::Result<T, Error>;

pub trait Handler {
fn handler(&self) -> Result<()>;
fn handler(&self, logger: &mut env_logger::Builder) -> Result<()>;
}

/// Create a cli for quark
#[derive(Parser, Debug)]
#[clap(version, author)]
pub struct Cli {
/// The level of verbosity.
#[clap(short, long, parse(from_occurrences))]
pub(crate) verbose: usize,

/// The subcommand to apply
#[clap(subcommand)]
pub(crate) command: Command,
}
Expand Down
42 changes: 41 additions & 1 deletion src/cli/run.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,16 @@
extern crate execute;
use crate::{
config::{read_config_from_file, QuarkConfig},
helper::extract_quardle,
};

use super::{Handler, Result};
use clap::Args;

use std::process::Command;

use log::{info, LevelFilter};

/// Arguments for `RunCommand`
///
/// Usage :
Expand All @@ -14,11 +24,41 @@ pub struct RunCommand {
/// Folder containing the files generated by the quarks necessary to work
#[clap(short, long)]
output: String,

/// If set, the command will be executed silently.
#[clap(long)]
quiet: bool,
}

/// Method that will be called when the command is executed.
#[allow(clippy::useless_format)]
impl Handler for RunCommand {
fn handler(&self) -> Result<()> {
fn handler(&self, logger: &mut env_logger::Builder) -> Result<()> {
// Change logger behavior and init it
// If the logger was not initialized, nothing will be displayed into the console.
if self.quiet {
logger.filter_level(LevelFilter::Off);
}
logger.init();

extract_quardle(&self.output, &self.quardle)?;

info!("Start lumper...");
let quark_path = format!("{}/quark.json", &self.output);
let config: QuarkConfig = read_config_from_file(quark_path).unwrap();

let mut child = Command::new("./lumper")
.arg("-k")
.arg(format!("{}/{}", &self.output, config.kernel))
.arg("--cmdline")
.arg(format!("{}", config.kernel_cmdline))
.arg("--initramfs")
.arg(format!("{}/{}", &self.output, config.initramfs))
.spawn()
.expect("lumper faild to start");

child.wait().expect("failed to wait on child");

Ok(())
}
}
26 changes: 26 additions & 0 deletions src/config.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
use std::{error::Error, fs::File, io::BufReader, path::Path};

use serde::Deserialize;

#[allow(dead_code)]
#[derive(Deserialize, Debug)]
pub struct QuarkConfig {
pub quardle: String,
pub kernel: String,
pub initramfs: String,
pub kernel_cmdline: String,
pub image: String,
pub kaps: String,
pub offline: bool,
pub bundle: String,
}

pub fn read_config_from_file<P: AsRef<Path>>(path: P) -> Result<QuarkConfig, Box<dyn Error>> {
let file = File::open(path)?;
let reader = BufReader::new(file);

// Read the JSON contents of the file as an instance of `QuarkConfig`.
let config = serde_json::from_reader(reader)?;

Ok(config)
}
21 changes: 21 additions & 0 deletions src/helper.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
use flate2::read::GzDecoder;
use log::info;
use std::{fs::File, io::Result, path::Path};
use tar::Archive;

/// Extract quardle archive to the output directory
pub fn extract_quardle(output: &str, quardle: &str) -> Result<()> {
if !Path::new(output).exists() {
let tar_gz = File::open(quardle)?;
let tar = GzDecoder::new(tar_gz);
let mut archive = Archive::new(tar);

info!("Unpacking quardle...");
archive.unpack(output)?;
info!("Done");
} else {
info!("quardle already exists");
}

Ok(())
}
28 changes: 27 additions & 1 deletion src/main.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,38 @@
use clap::StructOpt;
use cli::{Cli, Result};
use log::{log_enabled, Level, LevelFilter};
use std::io::Write;

mod cli;
mod config;
mod helper;

fn main() -> Result<()> {
let cli: Cli = Cli::parse();

cli.command().handler()?;
let mut builder = env_logger::Builder::new();
let logger = builder
.filter_level(match cli.verbose {
1 => LevelFilter::Debug,
2 => LevelFilter::Trace,
_ => LevelFilter::Info,
})
.format(|buf, record| {
if record.level() != Level::Info
|| log_enabled!(Level::Trace)
|| log_enabled!(Level::Debug)
{
return writeln!(
buf,
"{}: {}",
record.level().to_string().to_lowercase(),
record.args()
);
}
writeln!(buf, "{}", record.args())
});

cli.command().handler(logger)?;

Ok(())
}