Compare commits

..

No commits in common. 'cb1e1841b4b606f72cca46fd0c497d6596b39472' and 'f9900daeef7b816a02d686a97f468f5cd5e82381' have entirely different histories.

@ -1,8 +1,6 @@
build a minimal chroot/container/vm filesystem by taking a list of files and build a minimal chroot/container/vm filesystem by taking a list of files and
putting them and their necessary libs into a target rootfs directory putting them and their necessary libs into a target rootfs directory
this is linux only
example: example:
``` ```

@ -1,2 +0,0 @@
#!/bin/bash
find src -type f -name '*.rs' -exec rustfmt {} +

@ -2,8 +2,7 @@ use std::fs::read_dir;
use std::path::PathBuf; use std::path::PathBuf;
use crate::config::Config; use crate::config::Config;
use crate::result::Result; use crate::error::*;
use crate::serr;
use crate::util::mkdir; use crate::util::mkdir;
static DIRS: &[&str] = &[ static DIRS: &[&str] = &[
@ -11,7 +10,7 @@ static DIRS: &[&str] = &[
"usr", "var", "usr/bin", "usr", "var", "usr/bin",
]; ];
pub fn check(config: &Config) -> Result<()> { pub fn check(config: &Config) -> MkrootResult<()> {
if !&config.root_dir.exists() { if !&config.root_dir.exists() {
return Ok(()); return Ok(());
} }
@ -27,25 +26,24 @@ pub fn check(config: &Config) -> Result<()> {
Ok(()) Ok(())
} }
fn open(dir: &PathBuf, verbose: bool) -> Result<()> { fn open(dir: &PathBuf, verbose: bool) -> MkrootResult<()> {
if dir.exists() { if dir.exists() {
if verbose { if verbose {
println!("Checking directory {}", &dir.display()); println!("Checking directory {}", &dir.display());
} }
if let Err(e) = read_dir(&dir) { if let Err(e) = read_dir(&dir) {
return serr!( return Err(MkrootError::from(format!(
"Error opening directory ", "Error opening directory {}: {}",
&dir.display().to_string(), &dir.display(),
": ", e
&e.to_string() )));
);
} }
} }
Ok(()) Ok(())
} }
pub fn create(config: &Config) -> Result<()> { pub fn create(config: &Config) -> MkrootResult<()> {
if config.verbose { if config.verbose {
println!("Creating directory {}", &config.root_dir.display()); println!("Creating directory {}", &config.root_dir.display());
} }

@ -0,0 +1,49 @@
use std::fmt::{Display, Formatter, Result as FmtResult};
use std::io::Error as IoError;
use regex::Error as RegexError;
pub type MkrootResult<T> = Result<T, MkrootError>;
#[derive(Debug)]
pub enum MkrootError {
Io(IoError),
Regex(RegexError),
Custom(String),
Empty,
}
impl From<IoError> for MkrootError {
fn from(e: IoError) -> MkrootError {
MkrootError::Io(e)
}
}
impl From<RegexError> for MkrootError {
fn from(e: RegexError) -> MkrootError {
MkrootError::Regex(e)
}
}
impl From<String> for MkrootError {
fn from(e: String) -> MkrootError {
MkrootError::Custom(e)
}
}
impl From<()> for MkrootError {
fn from(_: ()) -> MkrootError {
MkrootError::Empty
}
}
impl Display for MkrootError {
fn fmt(&self, f: &mut Formatter) -> FmtResult {
match *self {
MkrootError::Io(ref e) => Display::fmt(e, f),
MkrootError::Regex(ref e) => Display::fmt(e, f),
MkrootError::Custom(ref e) => Display::fmt(e, f),
MkrootError::Empty => Display::fmt("Empty", f),
}
}
}

@ -6,8 +6,7 @@ use std::process::Command;
use regex::Regex; use regex::Regex;
use crate::config::Config; use crate::config::Config;
use crate::result::Result; use crate::error::*;
use crate::serr;
use crate::util::{copy_file, set_perms}; use crate::util::{copy_file, set_perms};
pub struct Files { pub struct Files {
@ -18,7 +17,7 @@ pub struct Files {
} }
impl Files { impl Files {
pub fn gather(config: &Config) -> Result<Files> { pub fn gather(config: &Config) -> MkrootResult<Files> {
let mut myfiles = Files { let mut myfiles = Files {
bins: Vec::new(), bins: Vec::new(),
sbins: Vec::new(), sbins: Vec::new(),
@ -56,7 +55,7 @@ impl Files {
Ok(myfiles) Ok(myfiles)
} }
pub fn copy(&self, config: &Config) -> Result<()> { pub fn copy(&self, config: &Config) -> MkrootResult<()> {
let mut target = PathBuf::from(&config.root_dir); let mut target = PathBuf::from(&config.root_dir);
target.push("bin"); target.push("bin");
copy_files(&self.bins, &target, 0o755, config.verbose)?; copy_files(&self.bins, &target, 0o755, config.verbose)?;
@ -77,7 +76,11 @@ impl Files {
} }
} }
pub fn set_linker_permissions(libs: &[PathBuf], dir: &PathBuf, verbose: bool) -> Result<()> { pub fn set_linker_permissions(
libs: &[PathBuf],
dir: &PathBuf,
verbose: bool,
) -> MkrootResult<()> {
for lib in libs { for lib in libs {
if let Some(fn_osstr) = &lib.file_name() { if let Some(fn_osstr) = &lib.file_name() {
if let Some(fn_str) = fn_osstr.to_str() { if let Some(fn_str) = fn_osstr.to_str() {
@ -98,19 +101,21 @@ pub fn set_linker_permissions(libs: &[PathBuf], dir: &PathBuf, verbose: bool) ->
Ok(()) Ok(())
} }
fn open(p: &PathBuf) -> Result<()> { fn open(p: &PathBuf) -> MkrootResult<()> {
if let Err(e) = File::open(&p) { if let Err(e) = File::open(&p) {
return serr!( return Err(MkrootError::from(format!(
"Error opening file (", "Error opening file ({}): {}",
&p.display().to_string(), &p.display(),
"): ", e
&e.to_string() )));
);
} }
Ok(()) Ok(())
} }
fn libs_from_ldd(file: &PathBuf, config: &Config) -> Result<(Vec<PathBuf>, Vec<PathBuf>)> { fn libs_from_ldd(
file: &PathBuf,
config: &Config,
) -> MkrootResult<(Vec<PathBuf>, Vec<PathBuf>)> {
let ldd = ldd(&file, &config)?; let ldd = ldd(&file, &config)?;
let mut libs: Vec<PathBuf> = Vec::new(); let mut libs: Vec<PathBuf> = Vec::new();
@ -145,7 +150,12 @@ fn libs_from_ldd(file: &PathBuf, config: &Config) -> Result<(Vec<PathBuf>, Vec<P
Ok((libs, lib64s)) Ok((libs, lib64s))
} }
fn copy_files(files: &[PathBuf], target: &PathBuf, mode: u32, verbose: bool) -> Result<()> { fn copy_files(
files: &[PathBuf],
target: &PathBuf,
mode: u32,
verbose: bool,
) -> MkrootResult<()> {
for f in files { for f in files {
let mut t = PathBuf::from(&target); let mut t = PathBuf::from(&target);
if let Some(filename) = &f.file_name() { if let Some(filename) = &f.file_name() {
@ -165,7 +175,7 @@ fn copy_files(files: &[PathBuf], target: &PathBuf, mode: u32, verbose: bool) ->
Ok(()) Ok(())
} }
fn ldd(file: &PathBuf, config: &Config) -> Result<String> { fn ldd(file: &PathBuf, config: &Config) -> MkrootResult<String> {
match Command::new(&config.ldd).arg(file).output() { match Command::new(&config.ldd).arg(file).output() {
Ok(output) => { Ok(output) => {
if output.status.success() { if output.status.success() {
@ -189,12 +199,11 @@ fn ldd(file: &PathBuf, config: &Config) -> Result<String> {
Ok(String::new()) Ok(String::new())
} }
} }
Err(e) => serr!( Err(e) => Err(MkrootError::from(format!(
"Error running ldd (", "Error running ldd ({}): {}",
&config.ldd.display().to_string(), &config.ldd.display(),
"): ", e
&e.to_string() ))),
),
} }
} }

@ -0,0 +1,3 @@
mod mkroot_files;
pub use mkroot_files::*;

@ -1,6 +0,0 @@
#[macro_export]
macro_rules! serr {
($($arg:tt)*) => {
Err(Box::from([$($arg)*].concat()))
};
}

@ -3,11 +3,9 @@ extern crate structopt;
mod config; mod config;
mod dirs; mod dirs;
mod error;
mod files; mod files;
#[macro_use]
mod macros;
mod os_release; mod os_release;
mod result;
mod skel; mod skel;
mod util; mod util;
@ -16,9 +14,8 @@ use std::path::PathBuf;
use structopt::StructOpt; use structopt::StructOpt;
use config::Config; use config::Config;
use result::Result;
fn main() -> Result<()> { fn main() -> error::MkrootResult<()> {
let config: Config = StructOpt::from_args(); let config: Config = StructOpt::from_args();
if config.verbose { if config.verbose {
@ -43,7 +40,10 @@ fn main() -> Result<()> {
files::set_linker_permissions(&mkrootfiles.lib64s, &d, config.verbose)?; files::set_linker_permissions(&mkrootfiles.lib64s, &d, config.verbose)?;
if let Err(e) = os_release::os_release(&config) { if let Err(e) = os_release::os_release(&config) {
return serr!("Error creating etc/os-release: ", &e.to_string()); return Err(error::MkrootError::from(format!(
"Error creating etc/os-release: {}",
e
)));
} }
if config.skel != PathBuf::new() { if config.skel != PathBuf::new() {

@ -4,10 +4,9 @@ use std::os::unix::fs::PermissionsExt;
use std::path::PathBuf; use std::path::PathBuf;
use crate::config::Config; use crate::config::Config;
use crate::result::Result; use crate::error::{MkrootError, MkrootResult};
use crate::serr;
pub fn os_release(config: &Config) -> Result<()> { pub fn os_release(config: &Config) -> MkrootResult<()> {
let mut path = PathBuf::from(&config.root_dir); let mut path = PathBuf::from(&config.root_dir);
path.push("etc/os-release"); path.push("etc/os-release");
@ -29,21 +28,19 @@ pub fn os_release(config: &Config) -> Result<()> {
let mut perms = meta.permissions(); let mut perms = meta.permissions();
perms.set_mode(0o644); perms.set_mode(0o644);
if let Err(e) = set_permissions(&path, perms) { if let Err(e) = set_permissions(&path, perms) {
return serr!( return Err(MkrootError::from(format!(
"Error setting permissions ", "Error setting permissions {}: {}",
&path.display().to_string(), &path.display(),
": ", e
&e.to_string() )));
);
} }
} }
Err(e) => { Err(e) => {
return serr!( return Err(MkrootError::from(format!(
"Error reading metadata ", "Error reading metadata {}: {}",
&path.display().to_string(), &path.display(),
": ", e
&e.to_string() )))
);
} }
} }

@ -1 +0,0 @@
pub type Result<T> = std::result::Result<T, Box<dyn std::error::Error>>;

@ -3,10 +3,10 @@ use std::os::unix::fs::PermissionsExt;
use std::path::PathBuf; use std::path::PathBuf;
use crate::config::Config; use crate::config::Config;
use crate::result::Result; use crate::error::*;
use crate::util::{copy_file, get_perms, mkdir, set_perms}; use crate::util::{copy_file, get_perms, mkdir, set_perms};
pub fn copy(config: &Config) -> Result<()> { pub fn copy(config: &Config) -> MkrootResult<()> {
if config.verbose { if config.verbose {
println!( println!(
"Copying skel {} to {}", "Copying skel {} to {}",
@ -18,7 +18,7 @@ pub fn copy(config: &Config) -> Result<()> {
copy_dir(&config.skel, &config.root_dir, config.verbose) copy_dir(&config.skel, &config.root_dir, config.verbose)
} }
fn copy_dir(src: &PathBuf, dst: &PathBuf, verbose: bool) -> Result<()> { fn copy_dir(src: &PathBuf, dst: &PathBuf, verbose: bool) -> MkrootResult<()> {
match read_dir(&src) { match read_dir(&src) {
Ok(src_dir) => { Ok(src_dir) => {
for entry in src_dir { for entry in src_dir {
@ -45,13 +45,11 @@ fn copy_dir(src: &PathBuf, dst: &PathBuf, verbose: bool) -> Result<()> {
} }
mkdir(&new_dst)?; mkdir(&new_dst)?;
} else if !new_dst.is_dir() { } else if !new_dst.is_dir() {
return serr!( return Err(MkrootError::from(format!(
"Error: skel ", "Error: skel {} is a directory but target {} isn't",
&entry_path.display().to_string(), &entry_path.display(),
" is a directory but target ", &new_dst.display()
&new_dst.display().to_string(), )));
" isn't"
);
} }
let entry_perms = get_perms(&entry_path)?; let entry_perms = get_perms(&entry_path)?;
@ -73,23 +71,21 @@ fn copy_dir(src: &PathBuf, dst: &PathBuf, verbose: bool) -> Result<()> {
} }
} }
Err(e) => { Err(e) => {
return serr!( return Err(MkrootError::from(format!(
"Error getting directory entry in ", "Error getting directory entry in {}: {}",
&src.display().to_string(), &src.display(),
": ", e
&e.to_string() )))
);
} }
} }
} }
} }
Err(e) => { Err(e) => {
return serr!( return Err(MkrootError::from(format!(
"Error opening directory ", "Error opening directory {}: {}",
&src.display().to_string(), &src.display(),
": ", e
&e.to_string() )))
);
} }
}; };

@ -1,58 +0,0 @@
use std::fs::{copy, create_dir, metadata, set_permissions, Permissions};
use std::path::PathBuf;
use crate::result::Result;
use crate::serr;
pub fn get_perms(path: &PathBuf) -> Result<Permissions> {
match metadata(path) {
Ok(meta) => Ok(meta.permissions()),
Err(e) => serr!(
"Error retrieving metadata ",
&path.display().to_string(),
": ",
&e.to_string()
),
}
}
pub fn set_perms(path: &PathBuf, perms: Permissions) -> Result<()> {
if let Err(e) = set_permissions(path, perms) {
return serr!(
"Error setting permissions ",
&path.display().to_string(),
": ",
&e.to_string(),
);
}
Ok(())
}
pub fn mkdir(dir: &PathBuf) -> Result<()> {
if let Err(e) = create_dir(&dir) {
return serr!(
"Error creating directory ",
&dir.display().to_string(),
": ",
&e.to_string()
);
}
Ok(())
}
pub fn copy_file(src: &PathBuf, dst: &PathBuf) -> Result<()> {
if let Err(e) = copy(&src, &dst) {
return serr!(
"Error copying file from ",
&src.display().to_string(),
" to ",
&dst.display().to_string(),
": ",
&e.to_string()
);
}
Ok(())
}

@ -0,0 +1,17 @@
use std::fs::copy;
use std::path::PathBuf;
use crate::error::*;
pub fn copy_file(src: &PathBuf, dst: &PathBuf) -> MkrootResult<()> {
if let Err(e) = copy(&src, &dst) {
return Err(MkrootError::from(format!(
"Error copying file from {} to {}: {}",
&src.display(),
&dst.display(),
e
)));
}
Ok(())
}

@ -0,0 +1,16 @@
use std::fs::create_dir;
use std::path::PathBuf;
use crate::error::*;
pub fn mkdir(dir: &PathBuf) -> MkrootResult<()> {
if let Err(e) = create_dir(&dir) {
return Err(MkrootError::from(format!(
"Error creating directory {}: {}",
&dir.display(),
e
)));
}
Ok(())
}

@ -0,0 +1,7 @@
mod copy_file;
mod mkdir;
mod perms;
pub use crate::util::copy_file::copy_file;
pub use crate::util::mkdir::mkdir;
pub use crate::util::perms::*;

@ -0,0 +1,27 @@
use std::fs::{metadata, set_permissions, Permissions};
use std::path::PathBuf;
use crate::error::*;
pub fn get_perms(path: &PathBuf) -> MkrootResult<Permissions> {
match metadata(path) {
Ok(meta) => Ok(meta.permissions()),
Err(e) => Err(MkrootError::from(format!(
"Error retrieving metadata {}: {}",
path.display(),
e
))),
}
}
pub fn set_perms(path: &PathBuf, perms: Permissions) -> MkrootResult<()> {
if let Err(e) = set_permissions(path, perms) {
return Err(MkrootError::from(format!(
"Error setting permissions {}: {}",
path.display(),
e
)));
}
Ok(())
}
Loading…
Cancel
Save