use tempdir to have a consistent filesystem during build

This commit is contained in:
Michael 2018-08-16 20:42:28 +00:00
parent 046594bec7
commit 4dbdcd6797
6 changed files with 106 additions and 28 deletions

37
Cargo.lock generated
View file

@ -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"

View file

@ -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"

View file

@ -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(())
}

View file

@ -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,
}))
}
}

View file

@ -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;

View file

@ -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))))
}
}))
}