Compare commits

...

10 Commits

@ -1,6 +1,8 @@
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
this is linux only
example:
```

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

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

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

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

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

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

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

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

@ -0,0 +1,58 @@
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(())
}

@ -1,17 +0,0 @@
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(())
}

@ -1,16 +0,0 @@
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(())
}

@ -1,7 +0,0 @@
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::*;

@ -1,27 +0,0 @@
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