use tempdir to have a consistent filesystem during build
This commit is contained in:
parent
046594bec7
commit
4dbdcd6797
6 changed files with 106 additions and 28 deletions
37
Cargo.lock
generated
37
Cargo.lock
generated
|
@ -192,6 +192,7 @@ dependencies = [
|
|||
"hmac 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"hyper 0.12.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"lazy_static 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"mktemp 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"notify 4.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"regex 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"secstr 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
|
@ -504,6 +505,14 @@ dependencies = [
|
|||
"ws2_32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "mktemp"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"uuid 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "net2"
|
||||
version = "0.2.33"
|
||||
|
@ -569,6 +578,16 @@ dependencies = [
|
|||
"proc-macro2 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand"
|
||||
version = "0.3.22"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand"
|
||||
version = "0.4.2"
|
||||
|
@ -617,6 +636,11 @@ name = "rustc-demangle"
|
|||
version = "0.1.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "rustc-serialize"
|
||||
version = "0.3.24"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "rustc_version"
|
||||
version = "0.2.3"
|
||||
|
@ -960,6 +984,15 @@ name = "utf8-ranges"
|
|||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "uuid"
|
||||
version = "0.1.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"rand 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "vec_map"
|
||||
version = "0.8.1"
|
||||
|
@ -1090,6 +1123,7 @@ dependencies = [
|
|||
"checksum mio 0.6.15 (registry+https://github.com/rust-lang/crates.io-index)" = "4fcfcb32d63961fb6f367bfd5d21e4600b92cd310f71f9dca25acae196eb1560"
|
||||
"checksum miow 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "3e690c5df6b2f60acd45d56378981e827ff8295562fc8d34f573deb267a59cd1"
|
||||
"checksum miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f2f3b1cf331de6896aabf6e9d55dca90356cc9960cca7eaaf408a355ae919"
|
||||
"checksum mktemp 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "77001ceb9eed65439f3dc2a2543f9ba1417d912686bf224a7738d0966e6dcd69"
|
||||
"checksum net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)" = "42550d9fb7b6684a6d404d9fa7250c2eb2646df731d1c06afc06dcee9e1bcf88"
|
||||
"checksum nix 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "bfb3ddedaa14746434a02041940495bf11325c22f6d36125d3bdd56090d50a79"
|
||||
"checksum nodrop 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)" = "9a2228dca57108069a5262f2ed8bd2e82496d2e074a06d1ccc7ce1687b6ae0a2"
|
||||
|
@ -1097,12 +1131,14 @@ dependencies = [
|
|||
"checksum num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c51a3322e4bca9d212ad9a158a02abc6934d005490c054a2778df73a70aa0a30"
|
||||
"checksum proc-macro2 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)" = "762eea716b821300a86da08870a64b597304866ceb9f54a11d67b4cf56459c6a"
|
||||
"checksum quote 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)" = "ed7d650913520df631972f21e104a4fa2f9c82a14afc65d17b388a2e29731e7c"
|
||||
"checksum rand 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)" = "15a732abf9d20f0ad8eeb6f909bf6868722d9a06e1e50802b6a70351f40b4eb1"
|
||||
"checksum rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "eba5f8cb59cc50ed56be8880a5c7b496bfd9bd26394e176bc67884094145c2c5"
|
||||
"checksum redox_syscall 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)" = "c214e91d3ecf43e9a4e41e578973adeb14b474f2bee858742d127af75a0112b1"
|
||||
"checksum redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7e891cfe48e9100a70a3b6eb652fef28920c117d366339687bd5576160db0f76"
|
||||
"checksum regex 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "5bbbea44c5490a1e84357ff28b7d518b4619a159fed5d25f6c1de2d19cc42814"
|
||||
"checksum regex-syntax 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "747ba3b235651f6e2f67dfa8bcdcd073ddb7c243cb21c442fc12395dfcac212d"
|
||||
"checksum rustc-demangle 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "bcfe5b13211b4d78e5c2cadfebd7769197d95c639c35a50057eb4c05de811395"
|
||||
"checksum rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)" = "dcf128d1287d2ea9d80910b5f1120d0b8eede3fbf1abe91c40d39ea7d51e6fda"
|
||||
"checksum rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a"
|
||||
"checksum ryu 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "16aa12da69951804cddf5f74d96abcc414a31b064e610dc81e37c1536082f491"
|
||||
"checksum same-file 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "cfb6eded0b06a0b512c8ddbcf04089138c9b4362c2f696f3c3d76039d68f3637"
|
||||
|
@ -1144,6 +1180,7 @@ dependencies = [
|
|||
"checksum unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc"
|
||||
"checksum unreachable 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "382810877fe448991dfc7f0dd6e3ae5d58088fd0ea5e35189655f84e6814fa56"
|
||||
"checksum utf8-ranges 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "662fab6525a98beff2921d7f61a39e7d59e0b425ebc7d0d9e66d316e55124122"
|
||||
"checksum uuid 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)" = "78c590b5bd79ed10aad8fb75f078a59d8db445af6c743e55c4a53227fc01c13f"
|
||||
"checksum vec_map 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "05c78687fb1a80548ae3250346c3db86a80a7cdd77bda190189f2d0a0987c81a"
|
||||
"checksum version_check 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "7716c242968ee87e5542f8021178248f267f295a5c4803beae8b8b7fd9bc6051"
|
||||
"checksum void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d"
|
||||
|
|
|
@ -16,6 +16,7 @@ sha-1 = "0.7"
|
|||
failure = "0.1"
|
||||
futures = "0.1"
|
||||
hyper = "0.12"
|
||||
mktemp = "0.3"
|
||||
lazy_static = "1.1"
|
||||
notify = "4.0"
|
||||
regex = "1.0"
|
||||
|
|
|
@ -11,9 +11,11 @@ extern crate generic_array;
|
|||
extern crate structopt;
|
||||
|
||||
use std::collections::HashMap;
|
||||
use std::env;
|
||||
use std::io::{self, Read};
|
||||
use std::iter::FromIterator;
|
||||
use std::path::PathBuf;
|
||||
use std::process::Command;
|
||||
|
||||
use failure::{err_msg, Error};
|
||||
use generic_array::GenericArray;
|
||||
|
@ -32,7 +34,6 @@ struct Opt {
|
|||
#[derive(Debug, Serialize, Deserialize)]
|
||||
struct Config {
|
||||
secret: String,
|
||||
outdir: PathBuf,
|
||||
#[serde(default)]
|
||||
disable_hmac_verify: bool,
|
||||
}
|
||||
|
@ -43,6 +44,16 @@ struct Payload {
|
|||
headers: HashMap<String, String>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
struct RepositoryInfo {
|
||||
clone_url: String,
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
struct GithubPayload {
|
||||
repository: RepositoryInfo,
|
||||
}
|
||||
|
||||
fn main() -> Result<(), Error> {
|
||||
let args = Opt::from_args();
|
||||
let config: Config = serde_json::from_str(&args.config)?;
|
||||
|
@ -50,9 +61,7 @@ fn main() -> Result<(), Error> {
|
|||
|
||||
let mut payload = String::new();
|
||||
io::stdin().read_to_string(&mut payload)?;
|
||||
println!("raw payload: {}", payload);
|
||||
let payload: Payload = serde_json::from_str(&payload)?;
|
||||
println!("processed payload: {}", payload.body);
|
||||
|
||||
if !config.disable_hmac_verify {
|
||||
let secret = GenericArray::from_iter(config.secret.bytes());
|
||||
|
@ -75,6 +84,17 @@ fn main() -> Result<(), Error> {
|
|||
assert!(left == right, "HMAC signature didn't match",);
|
||||
}
|
||||
|
||||
println!("gonna clone it to {:?}", config.outdir);
|
||||
let payload: GithubPayload = serde_json::from_str(&payload.body)?;
|
||||
let mut target_path = PathBuf::from(env::var("DIP_WORKDIR")?);
|
||||
target_path.push("repository");
|
||||
println!("{:?}", &target_path);
|
||||
Command::new("git")
|
||||
.arg("clone")
|
||||
.arg(&payload.repository.clone_url)
|
||||
.arg("--recursive")
|
||||
.arg("--depth")
|
||||
.arg("1")
|
||||
.arg(&target_path)
|
||||
.output()?;
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
@ -40,6 +40,11 @@ impl Handler {
|
|||
let program = programs
|
||||
.get(handler)
|
||||
.ok_or(err_msg(format!("'{}' is not a valid executable", handler)))
|
||||
.and_then(|value| {
|
||||
value
|
||||
.canonicalize()
|
||||
.map_err(|_| err_msg("failed to canonicalize the path"))
|
||||
})
|
||||
.map(|value| value.clone())?;
|
||||
Action::Exec(program)
|
||||
}
|
||||
|
@ -47,7 +52,8 @@ impl Handler {
|
|||
let config = config.clone();
|
||||
Ok(Handler { config, action })
|
||||
}
|
||||
pub fn run(&self, input: JsonValue) -> Result<JsonValue, Error> {
|
||||
|
||||
pub fn run(&self, temp_path: &PathBuf, input: JsonValue) -> Result<JsonValue, Error> {
|
||||
let config = {
|
||||
let mut buf: Vec<u8> = Vec::new();
|
||||
{
|
||||
|
@ -61,7 +67,9 @@ impl Handler {
|
|||
Action::Command(ref cmd) => {
|
||||
// TODO: allow some kind of simple variable replacement
|
||||
let output = Command::new("/bin/bash")
|
||||
.current_dir(&temp_path)
|
||||
.env("DIP_ROOT", "lol")
|
||||
.env("DIP_WORKDIR", temp_path)
|
||||
.arg("-c")
|
||||
.arg(cmd)
|
||||
.output()?;
|
||||
|
@ -79,7 +87,9 @@ impl Handler {
|
|||
}
|
||||
Action::Exec(ref path) => {
|
||||
let mut child = Command::new(&path)
|
||||
.current_dir(&temp_path)
|
||||
.env("DIP_ROOT", "")
|
||||
.env("DIP_WORKDIR", temp_path)
|
||||
.arg("--config")
|
||||
.arg(config)
|
||||
.stdin(Stdio::piped())
|
||||
|
@ -108,11 +118,12 @@ impl Handler {
|
|||
output
|
||||
}
|
||||
};
|
||||
|
||||
let stdout = String::from_utf8(output.stdout).unwrap_or_else(|_| String::new());
|
||||
let stderr = String::from_utf8(output.stderr).unwrap_or_else(|_| String::new());
|
||||
Ok(json!({
|
||||
"stdout": stdout,
|
||||
"stderr": stderr,
|
||||
}))
|
||||
"stdout": stdout,
|
||||
"stderr": stderr,
|
||||
}))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
extern crate failure;
|
||||
extern crate futures;
|
||||
extern crate hyper;
|
||||
extern crate mktemp;
|
||||
extern crate serde;
|
||||
#[macro_use]
|
||||
extern crate serde_json;
|
||||
|
|
|
@ -2,6 +2,7 @@ use std::collections::HashMap;
|
|||
|
||||
use futures::{future, Future, Stream};
|
||||
use hyper::{Body, Error, Request, Response, StatusCode};
|
||||
use mktemp::Temp;
|
||||
|
||||
use {HOOKS, URIPATTERN};
|
||||
|
||||
|
@ -51,26 +52,33 @@ pub fn dip_service(req: Request<Body>) -> Box<Future<Item = Response<Body>, Erro
|
|||
"method": method,
|
||||
});
|
||||
let hooks = HOOKS.lock().unwrap();
|
||||
let hook = hooks.get(&name).unwrap();
|
||||
let (code, msg) = hook.iter()
|
||||
.fold(Ok(req_obj), |prev, handler| {
|
||||
prev.and_then(|val| handler.run(val))
|
||||
})
|
||||
.map(|res| {
|
||||
(
|
||||
StatusCode::ACCEPTED,
|
||||
format!(
|
||||
"stdout:\n{}\n\nstderr:\n{}",
|
||||
res.get("stdout").and_then(|v| v.as_str()).unwrap_or(""),
|
||||
res.get("stderr").and_then(|v| v.as_str()).unwrap_or(""),
|
||||
),
|
||||
)
|
||||
})
|
||||
.unwrap_or_else(|err| (StatusCode::BAD_REQUEST, format!("Error: {}", err)));
|
||||
Response::builder()
|
||||
.status(code)
|
||||
.body(Body::from(msg))
|
||||
.unwrap_or_else(|err| Response::new(Body::from(format!("{}", err))))
|
||||
{
|
||||
let mut temp_dir = Temp::new_dir().unwrap();
|
||||
let temp_path = temp_dir.to_path_buf();
|
||||
assert!(temp_path.exists());
|
||||
|
||||
let hook = hooks.get(&name).unwrap();
|
||||
let (code, msg) = hook.iter()
|
||||
.fold(Ok(req_obj), |prev, handler| {
|
||||
prev.and_then(|val| handler.run(&temp_path, val))
|
||||
})
|
||||
.map(|res| {
|
||||
(
|
||||
StatusCode::ACCEPTED,
|
||||
format!(
|
||||
"stdout:\n{}\n\nstderr:\n{}",
|
||||
res.get("stdout").and_then(|v| v.as_str()).unwrap_or(""),
|
||||
res.get("stderr").and_then(|v| v.as_str()).unwrap_or(""),
|
||||
),
|
||||
)
|
||||
})
|
||||
.unwrap_or_else(|err| (StatusCode::BAD_REQUEST, format!("Error: {:?}", err)));
|
||||
temp_dir.release();
|
||||
Response::builder()
|
||||
.status(code)
|
||||
.body(Body::from(msg))
|
||||
.unwrap_or_else(|err| Response::new(Body::from(format!("{}", err))))
|
||||
}
|
||||
}))
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue