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::collections::HashMap;
|
||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
use std::os::unix::io::FromRawFd;
|
use std::os::unix::io::FromRawFd;
|
||||||
|
use std::path::Path;
|
||||||
|
|
||||||
use clap::{App, AppSettings};
|
|
||||||
use nix::fcntl::OFlag;
|
use nix::fcntl::OFlag;
|
||||||
use nix::sys::socket;
|
use nix::sys::socket;
|
||||||
use nix::unistd;
|
use nix::unistd;
|
||||||
|
|
||||||
pub fn run() -> Result<()> {
|
pub struct RunArgs<'a> {
|
||||||
// process arguments
|
pub spec: Option<&'a Path>,
|
||||||
let matches = App::new("clone-shim")
|
pub debug: bool,
|
||||||
.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();
|
|
||||||
|
|
||||||
let (binary, trailing) = {
|
pub binary: &'a Path,
|
||||||
let mut argv = matches.values_of("binary").unwrap();
|
pub binary_args: Vec<&'a str>,
|
||||||
|
}
|
||||||
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 fn run(args: &RunArgs) -> Result<()> {
|
||||||
// parse the specification
|
// 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") {
|
if m.ends_with(".json") {
|
||||||
let f = std::fs::File::open(m)?;
|
let f = std::fs::File::open(m)?;
|
||||||
Ok(serde_json::from_reader(f)?)
|
Ok(serde_json::from_reader(f)?)
|
||||||
@ -75,13 +51,11 @@ pub fn run() -> Result<()> {
|
|||||||
let sockets = create_sockets(sockets)?;
|
let sockets = create_sockets(sockets)?;
|
||||||
|
|
||||||
// spawn all processes
|
// spawn all processes
|
||||||
let debug = matches.is_present("debug");
|
|
||||||
|
|
||||||
Spawner {
|
Spawner {
|
||||||
spec: &spec,
|
spec: &spec,
|
||||||
binary,
|
binary: args.binary,
|
||||||
trailing: &trailing,
|
binary_args: &args.binary_args,
|
||||||
debug,
|
debug: args.debug,
|
||||||
|
|
||||||
pipes,
|
pipes,
|
||||||
sockets,
|
sockets,
|
||||||
|
51
src/main.rs
51
src/main.rs
@ -1,9 +1,55 @@
|
|||||||
use log::{error, info};
|
use log::{error, info};
|
||||||
|
|
||||||
use clone_shim::run;
|
use clone_shim::{run, RunArgs};
|
||||||
|
|
||||||
|
use std::path::Path;
|
||||||
|
|
||||||
|
use clap::{App, AppSettings};
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
std::process::exit(match run() {
|
// 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(_) => {
|
Ok(_) => {
|
||||||
info!("launched successfully");
|
info!("launched successfully");
|
||||||
exitcode::OK
|
exitcode::OK
|
||||||
@ -12,5 +58,6 @@ fn main() {
|
|||||||
error!("error: {}", e);
|
error!("error: {}", e);
|
||||||
-1
|
-1
|
||||||
}
|
}
|
||||||
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -6,6 +6,7 @@ use crate::{Error, Result};
|
|||||||
use std::ffi::CString;
|
use std::ffi::CString;
|
||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
use std::net::TcpListener;
|
use std::net::TcpListener;
|
||||||
|
use std::os::unix::ffi::OsStrExt;
|
||||||
use std::os::unix::io::IntoRawFd;
|
use std::os::unix::io::IntoRawFd;
|
||||||
|
|
||||||
pub struct PreparedArgs(Vec<PreparedArg>);
|
pub struct PreparedArgs(Vec<PreparedArg>);
|
||||||
@ -162,7 +163,11 @@ impl PreparedArg {
|
|||||||
trigger: &mut TriggerData,
|
trigger: &mut TriggerData,
|
||||||
) -> Result<Vec<CString>> {
|
) -> Result<Vec<CString>> {
|
||||||
match self {
|
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::Entrypoint => Ok(vec![CString::new(entrypoint).unwrap()]),
|
||||||
|
|
||||||
PreparedArg::Pipe(p) => Ok(vec![CString::new(p.into_raw_fd().to_string()).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
|
PreparedArg::Trailing => Ok(spawner
|
||||||
.trailing
|
.binary_args
|
||||||
.iter()
|
.iter()
|
||||||
.map(|s| CString::new(*s).unwrap())
|
.map(|s| CString::new(*s).unwrap())
|
||||||
.collect()),
|
.collect()),
|
||||||
|
@ -14,7 +14,7 @@ use std::ffi::CString;
|
|||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
use std::io::Read;
|
use std::io::Read;
|
||||||
use std::os::unix::io::{AsRawFd, FromRawFd, IntoRawFd};
|
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::signal::{kill, Signal};
|
||||||
use nix::sys::socket::{recvmsg, ControlMessageOwned, MsgFlags};
|
use nix::sys::socket::{recvmsg, ControlMessageOwned, MsgFlags};
|
||||||
@ -24,8 +24,8 @@ const BUFFER_SIZE: usize = 1024;
|
|||||||
|
|
||||||
pub struct Spawner<'a> {
|
pub struct Spawner<'a> {
|
||||||
pub spec: &'a Specification,
|
pub spec: &'a Specification,
|
||||||
pub binary: &'a str,
|
pub binary: &'a Path,
|
||||||
pub trailing: &'a Vec<&'a str>,
|
pub binary_args: &'a Vec<&'a str>,
|
||||||
pub debug: bool,
|
pub debug: bool,
|
||||||
|
|
||||||
pub pipes: HashMap<String, PipePair>,
|
pub pipes: HashMap<String, PipePair>,
|
||||||
|
Loading…
Reference in New Issue
Block a user