moved argument processing to main.rs
This commit is contained in:
parent
763fab12d8
commit
05fe72e733
50
src/lib.rs
50
src/lib.rs
@ -13,47 +13,23 @@ use specification::Specification;
|
||||
use std::collections::HashMap;
|
||||
use std::fs::File;
|
||||
use std::os::unix::io::FromRawFd;
|
||||
use std::path::Path;
|
||||
|
||||
use clap::{App, AppSettings};
|
||||
use nix::fcntl::OFlag;
|
||||
use nix::sys::socket;
|
||||
use nix::unistd;
|
||||
|
||||
pub fn run() -> Result<()> {
|
||||
// process arguments
|
||||
let matches = App::new("clone-shim")
|
||||
.version(env!("GIT_HASH"))
|
||||
.author("Jake Hillion <jake@hillion.co.uk>")
|
||||
.about("Launch a multi entrypoint app, cloning as requested by an external specification or the ELF.")
|
||||
.arg(clap::Arg::new("spec").long("specification").short('s').help("Provide the specification as an external JSON file.").takes_value(true))
|
||||
.setting(AppSettings::TrailingVarArg)
|
||||
.arg(clap::Arg::new("verbose").long("verbose").short('v').help("Use verbose logging.").takes_value(false))
|
||||
.arg(clap::Arg::new("debug").long("debug").short('d').help("Stop each spawned application process so that it can be attached to.").takes_value(false))
|
||||
.arg(clap::Arg::new("binary").index(1).help("Binary and arguments to launch with the shim").required(true).multiple_values(true))
|
||||
.get_matches();
|
||||
pub struct RunArgs<'a> {
|
||||
pub spec: Option<&'a Path>,
|
||||
pub debug: bool,
|
||||
|
||||
let (binary, trailing) = {
|
||||
let mut argv = matches.values_of("binary").unwrap();
|
||||
|
||||
let binary = argv.next().unwrap();
|
||||
let trailing: Vec<&str> = argv.collect();
|
||||
|
||||
(binary, trailing)
|
||||
};
|
||||
|
||||
// setup logging
|
||||
let env = env_logger::Env::new().filter_or(
|
||||
"LOG",
|
||||
if matches.is_present("verbose") {
|
||||
"debug"
|
||||
} else {
|
||||
"warn"
|
||||
},
|
||||
);
|
||||
env_logger::init_from_env(env);
|
||||
pub binary: &'a Path,
|
||||
pub binary_args: Vec<&'a str>,
|
||||
}
|
||||
|
||||
pub fn run(args: &RunArgs) -> Result<()> {
|
||||
// parse the specification
|
||||
let spec: Specification = if let Some(m) = matches.value_of("spec") {
|
||||
let spec: Specification = if let Some(m) = args.spec {
|
||||
if m.ends_with(".json") {
|
||||
let f = std::fs::File::open(m)?;
|
||||
Ok(serde_json::from_reader(f)?)
|
||||
@ -75,13 +51,11 @@ pub fn run() -> Result<()> {
|
||||
let sockets = create_sockets(sockets)?;
|
||||
|
||||
// spawn all processes
|
||||
let debug = matches.is_present("debug");
|
||||
|
||||
Spawner {
|
||||
spec: &spec,
|
||||
binary,
|
||||
trailing: &trailing,
|
||||
debug,
|
||||
binary: args.binary,
|
||||
binary_args: &args.binary_args,
|
||||
debug: args.debug,
|
||||
|
||||
pipes,
|
||||
sockets,
|
||||
|
65
src/main.rs
65
src/main.rs
@ -1,16 +1,63 @@
|
||||
use log::{error, info};
|
||||
|
||||
use clone_shim::run;
|
||||
use clone_shim::{run, RunArgs};
|
||||
|
||||
use std::path::Path;
|
||||
|
||||
use clap::{App, AppSettings};
|
||||
|
||||
fn main() {
|
||||
std::process::exit(match run() {
|
||||
Ok(_) => {
|
||||
info!("launched successfully");
|
||||
exitcode::OK
|
||||
}
|
||||
Err(e) => {
|
||||
error!("error: {}", e);
|
||||
-1
|
||||
// process arguments
|
||||
let matches = App::new("clone-shim")
|
||||
.version(env!("GIT_HASH"))
|
||||
.author("Jake Hillion <jake@hillion.co.uk>")
|
||||
.about("Launch a multi entrypoint app, cloning as requested by an external specification or the ELF.")
|
||||
.arg(clap::Arg::new("spec").long("specification").short('s').help("Provide the specification as an external JSON file.").takes_value(true))
|
||||
.setting(AppSettings::TrailingVarArg)
|
||||
.arg(clap::Arg::new("verbose").long("verbose").short('v').help("Use verbose logging.").takes_value(false))
|
||||
.arg(clap::Arg::new("debug").long("debug").short('d').help("Stop each spawned application process so that it can be attached to.").takes_value(false))
|
||||
.arg(clap::Arg::new("binary").index(1).help("Binary and arguments to launch with the shim").required(true).multiple_values(true))
|
||||
.get_matches();
|
||||
|
||||
// setup logging
|
||||
let env = env_logger::Env::new().filter_or(
|
||||
"LOG",
|
||||
if matches.is_present("verbose") {
|
||||
"debug"
|
||||
} else {
|
||||
"warn"
|
||||
},
|
||||
);
|
||||
env_logger::init_from_env(env);
|
||||
|
||||
// launch process
|
||||
// execute shimmed process
|
||||
std::process::exit({
|
||||
let (binary, binary_args) = {
|
||||
let mut argv = matches.values_of("binary").unwrap();
|
||||
|
||||
let binary = Path::new(argv.next().expect("one value is required"));
|
||||
let binary_args: Vec<&str> = argv.collect();
|
||||
|
||||
(binary, binary_args)
|
||||
};
|
||||
|
||||
let args = RunArgs {
|
||||
spec: matches.value_of("spec").map(Path::new),
|
||||
debug: matches.is_present("debug"),
|
||||
binary,
|
||||
binary_args,
|
||||
};
|
||||
|
||||
match run(&args) {
|
||||
Ok(_) => {
|
||||
info!("launched successfully");
|
||||
exitcode::OK
|
||||
}
|
||||
Err(e) => {
|
||||
error!("error: {}", e);
|
||||
-1
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
@ -6,6 +6,7 @@ use crate::{Error, Result};
|
||||
use std::ffi::CString;
|
||||
use std::fs::File;
|
||||
use std::net::TcpListener;
|
||||
use std::os::unix::ffi::OsStrExt;
|
||||
use std::os::unix::io::IntoRawFd;
|
||||
|
||||
pub struct PreparedArgs(Vec<PreparedArg>);
|
||||
@ -162,7 +163,11 @@ impl PreparedArg {
|
||||
trigger: &mut TriggerData,
|
||||
) -> Result<Vec<CString>> {
|
||||
match self {
|
||||
PreparedArg::BinaryName => Ok(vec![CString::new(spawner.binary).unwrap()]),
|
||||
PreparedArg::BinaryName => {
|
||||
Ok(vec![
|
||||
CString::new(spawner.binary.as_os_str().as_bytes()).unwrap()
|
||||
])
|
||||
}
|
||||
PreparedArg::Entrypoint => Ok(vec![CString::new(entrypoint).unwrap()]),
|
||||
|
||||
PreparedArg::Pipe(p) => Ok(vec![CString::new(p.into_raw_fd().to_string()).unwrap()]),
|
||||
@ -179,7 +184,7 @@ impl PreparedArg {
|
||||
}
|
||||
|
||||
PreparedArg::Trailing => Ok(spawner
|
||||
.trailing
|
||||
.binary_args
|
||||
.iter()
|
||||
.map(|s| CString::new(*s).unwrap())
|
||||
.collect()),
|
||||
|
@ -14,7 +14,7 @@ use std::ffi::CString;
|
||||
use std::fs::File;
|
||||
use std::io::Read;
|
||||
use std::os::unix::io::{AsRawFd, FromRawFd, IntoRawFd};
|
||||
use std::path::PathBuf;
|
||||
use std::path::{Path, PathBuf};
|
||||
|
||||
use nix::sys::signal::{kill, Signal};
|
||||
use nix::sys::socket::{recvmsg, ControlMessageOwned, MsgFlags};
|
||||
@ -24,8 +24,8 @@ const BUFFER_SIZE: usize = 1024;
|
||||
|
||||
pub struct Spawner<'a> {
|
||||
pub spec: &'a Specification,
|
||||
pub binary: &'a str,
|
||||
pub trailing: &'a Vec<&'a str>,
|
||||
pub binary: &'a Path,
|
||||
pub binary_args: &'a Vec<&'a str>,
|
||||
pub debug: bool,
|
||||
|
||||
pub pipes: HashMap<String, PipePair>,
|
||||
|
Loading…
Reference in New Issue
Block a user