add checks for executors environment

This commit is contained in:
b1ek 2024-03-04 02:55:27 +10:00
parent 6a33c3a244
commit 4970ffc4f3
Signed by: blek
GPG Key ID: 14546221E3595D0C
8 changed files with 331 additions and 3 deletions

235
Cargo.lock generated
View File

@ -118,6 +118,12 @@ dependencies = [
"generic-array", "generic-array",
] ]
[[package]]
name = "bumpalo"
version = "3.15.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d32a994c2b3ca201d9b263612a374263f05e7adde37c4707f693dcd375076d1f"
[[package]] [[package]]
name = "byteorder" name = "byteorder"
version = "1.5.0" version = "1.5.0"
@ -195,6 +201,31 @@ version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5"
[[package]]
name = "erased-serde"
version = "0.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "388979d208a049ffdfb22fa33b9c81942215b940910bccfe258caeb25d125cb3"
dependencies = [
"serde",
]
[[package]]
name = "femme"
version = "2.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cc04871e5ae3aa2952d552dae6b291b3099723bf779a8054281c1366a54613ef"
dependencies = [
"cfg-if",
"js-sys",
"log",
"serde",
"serde_derive",
"serde_json",
"wasm-bindgen",
"web-sys",
]
[[package]] [[package]]
name = "fnv" name = "fnv"
version = "1.0.7" version = "1.0.7"
@ -450,6 +481,15 @@ version = "1.0.10"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c" checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c"
[[package]]
name = "js-sys"
version = "0.3.68"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "406cda4b368d531c842222cf9d2600a9a4acce8d29423695379c6868a143a9ee"
dependencies = [
"wasm-bindgen",
]
[[package]] [[package]]
name = "libc" name = "libc"
version = "0.2.153" version = "0.2.153"
@ -477,6 +517,10 @@ name = "log"
version = "0.4.20" version = "0.4.20"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f"
dependencies = [
"serde",
"value-bag",
]
[[package]] [[package]]
name = "memchr" name = "memchr"
@ -744,6 +788,8 @@ name = "sandy"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"askama", "askama",
"femme",
"log",
"rand", "rand",
"serde", "serde",
"serde_json", "serde_json",
@ -784,6 +830,15 @@ dependencies = [
"syn 2.0.49", "syn 2.0.49",
] ]
[[package]]
name = "serde_fmt"
version = "1.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e1d4ddca14104cd60529e8c7f7ba71a2c8acd8f7f5cfcdc2faf97eeb7c3010a4"
dependencies = [
"serde",
]
[[package]] [[package]]
name = "serde_json" name = "serde_json"
version = "1.0.113" version = "1.0.113"
@ -875,6 +930,84 @@ dependencies = [
"warp", "warp",
] ]
[[package]]
name = "sval"
version = "2.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "82a2386bea23a121e4e72450306b1dd01078b6399af11b93897bf84640a28a59"
[[package]]
name = "sval_buffer"
version = "2.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b16c047898a0e19002005512243bc9ef1c1037aad7d03d6c594e234efec80795"
dependencies = [
"sval",
"sval_ref",
]
[[package]]
name = "sval_dynamic"
version = "2.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a74fb116e2ecdcb280b0108aa2ee4434df50606c3208c47ac95432730eaac20c"
dependencies = [
"sval",
]
[[package]]
name = "sval_fmt"
version = "2.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "10837b4f0feccef271b2b1c03784e08f6d0bb6d23272ec9e8c777bfadbb8f1b8"
dependencies = [
"itoa",
"ryu",
"sval",
]
[[package]]
name = "sval_json"
version = "2.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "891f5ecdf34ce61a8ab2d10f9cfdc303347b0afec4dad6702757419d2d8312a9"
dependencies = [
"itoa",
"ryu",
"sval",
]
[[package]]
name = "sval_nested"
version = "2.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "63fcffb4b79c531f38e3090788b64f3f4d54a180aacf02d69c42fa4e4bf284c3"
dependencies = [
"sval",
"sval_buffer",
"sval_ref",
]
[[package]]
name = "sval_ref"
version = "2.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "af725f9c2aa7cec4ca9c47da2cc90920c4c82d3fa537094c66c77a5459f5809d"
dependencies = [
"sval",
]
[[package]]
name = "sval_serde"
version = "2.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3d7589c649a03d21df40b9a926787d2c64937fa1dccec8d87c6cd82989a2e0a4"
dependencies = [
"serde",
"sval",
"sval_nested",
]
[[package]] [[package]]
name = "syn" name = "syn"
version = "1.0.109" version = "1.0.109"
@ -1109,6 +1242,42 @@ version = "0.7.6"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9"
[[package]]
name = "value-bag"
version = "1.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "126e423afe2dd9ac52142e7e9d5ce4135d7e13776c529d27fd6bc49f19e3280b"
dependencies = [
"value-bag-serde1",
"value-bag-sval2",
]
[[package]]
name = "value-bag-serde1"
version = "1.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ede32f342edc46e84bd41fd394ce2192b553de11725dd83b6223150610c21b44"
dependencies = [
"erased-serde",
"serde",
"serde_fmt",
]
[[package]]
name = "value-bag-sval2"
version = "1.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0024e44b25144c2f4d0ed35d39688e0090d57753e20fef38d08e0c1a40bdf23d"
dependencies = [
"sval",
"sval_buffer",
"sval_dynamic",
"sval_fmt",
"sval_json",
"sval_ref",
"sval_serde",
]
[[package]] [[package]]
name = "version_check" name = "version_check"
version = "0.9.4" version = "0.9.4"
@ -1161,6 +1330,72 @@ version = "0.11.0+wasi-snapshot-preview1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
[[package]]
name = "wasm-bindgen"
version = "0.2.91"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c1e124130aee3fb58c5bdd6b639a0509486b0338acaaae0c84a5124b0f588b7f"
dependencies = [
"cfg-if",
"serde",
"serde_json",
"wasm-bindgen-macro",
]
[[package]]
name = "wasm-bindgen-backend"
version = "0.2.91"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c9e7e1900c352b609c8488ad12639a311045f40a35491fb69ba8c12f758af70b"
dependencies = [
"bumpalo",
"log",
"once_cell",
"proc-macro2",
"quote",
"syn 2.0.49",
"wasm-bindgen-shared",
]
[[package]]
name = "wasm-bindgen-macro"
version = "0.2.91"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b30af9e2d358182b5c7449424f017eba305ed32a7010509ede96cdc4696c46ed"
dependencies = [
"quote",
"wasm-bindgen-macro-support",
]
[[package]]
name = "wasm-bindgen-macro-support"
version = "0.2.91"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "642f325be6301eb8107a83d12a8ac6c1e1c54345a7ef1a9261962dfefda09e66"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.49",
"wasm-bindgen-backend",
"wasm-bindgen-shared",
]
[[package]]
name = "wasm-bindgen-shared"
version = "0.2.91"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4f186bd2dcf04330886ce82d6f33dd75a7bfcf69ecf5763b89fcde53b6ac9838"
[[package]]
name = "web-sys"
version = "0.3.68"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "96565907687f7aceb35bc5fc03770a8a0471d82e479f25832f54a0e3f4b28446"
dependencies = [
"js-sys",
"wasm-bindgen",
]
[[package]] [[package]]
name = "windows-sys" name = "windows-sys"
version = "0.48.0" version = "0.48.0"

View File

@ -7,6 +7,8 @@ edition = "2021"
[dependencies] [dependencies]
askama = "0.12.1" askama = "0.12.1"
femme = "2.2.1"
log = "0.4.20"
rand = "0.8.5" rand = "0.8.5"
serde = { version = "1.0.196", features = ["derive"] } serde = { version = "1.0.196", features = ["derive"] }
serde_json = "1.0.113" serde_json = "1.0.113"

View File

@ -15,7 +15,7 @@ pub fn executors() -> Vec<Box<dyn Executor>> {
} }
pub fn executors_id() -> Vec<String> { pub fn executors_id() -> Vec<String> {
executors() filter_unavailable(&executors())
.iter() .iter()
.map(|x| x.id()) .map(|x| x.id())
.collect() .collect()
@ -27,7 +27,15 @@ pub fn get_executor<'a, T: Into<String>>(id: T, executors: &'a Vec<Box<dyn Execu
found found
} }
pub fn filter_unavailable<'a>(executors: &'a Vec<Box<dyn Executor>>) -> Vec<&Box<dyn Executor>> {
executors
.iter()
.filter(|x| x.available())
.collect()
}
pub trait Executor { pub trait Executor {
fn id(&self) -> String; fn id(&self) -> String;
fn exec(&self, code: String) -> Result<String, String>; fn exec(&self, code: String) -> Result<String, String>;
fn available(&self) -> bool;
} }

View File

@ -1,4 +1,4 @@
use std::{fs::create_dir_all, io::Read, process::{ChildStdout, ExitStatus}}; use std::{env, fs::{self, create_dir_all}, io::Read, process::{ChildStdout, ExitStatus}};
use rand::{distributions::Alphanumeric, Rng, thread_rng}; use rand::{distributions::Alphanumeric, Rng, thread_rng};
@ -41,4 +41,26 @@ pub fn get_stdout(stdout: Option<ChildStdout>) -> Result<String, String> {
}; };
Ok(ret) Ok(ret)
}
pub fn cmd_exists<T: Into<String>, B: From<bool>>(program: T) -> B {
let program: String = program.into();
if let Ok(path) = env::var("PATH") {
const SEP: char = {
if cfg!(unix) {
':'
} else {
';'
}
};
for p in path.split(SEP) {
let p_str = format!("{}/{}", p, program);
if fs::metadata(p_str).is_ok() {
return true.into();
}
}
}
false.into()
} }

View File

@ -6,9 +6,14 @@ use super::Executor;
use super::helper::*; use super::helper::*;
#[derive(Debug, Clone, Copy)]
pub struct NodeJSExecutor {} pub struct NodeJSExecutor {}
impl Executor for NodeJSExecutor { impl Executor for NodeJSExecutor {
fn available(&self) -> bool {
cmd_exists("node")
}
fn id(&self) -> String { fn id(&self) -> String {
"javascript".into() "javascript".into()
} }

View File

@ -10,6 +10,10 @@ use super::helper::*;
pub struct PhpExecutor {} pub struct PhpExecutor {}
impl Executor for PhpExecutor { impl Executor for PhpExecutor {
fn available(&self) -> bool {
cmd_exists("php")
}
fn id(&self) -> String { fn id(&self) -> String {
"php".into() "php".into()
} }

View File

@ -11,6 +11,34 @@ use super::helper::*;
pub struct PythonExecutor {} pub struct PythonExecutor {}
impl Executor for PythonExecutor { impl Executor for PythonExecutor {
fn available(&self) -> bool {
let cmd_ok = cmd_exists("python");
if cmd_ok {
let version_check =
Command::new("python")
.arg("--version")
.stdout(Stdio::piped())
.spawn();
if let Ok(version_check) = version_check {
if let Some(mut sout) = version_check.stdout {
let mut buf = String::new();
let res = sout.read_to_string(&mut buf);
if res.is_err() {
return false;
}
let is_py3 = buf.starts_with("Python 3");
if ! is_py3 {
log::warn!("`python` command is not a Python 3 interpreter.")
}
return is_py3
}
}
}
false
}
fn id(&self) -> String { fn id(&self) -> String {
"python".into() "python".into()
} }

View File

@ -3,7 +3,7 @@
use std::{fs::create_dir_all, net::SocketAddr, process::Stdio}; use std::{fs::create_dir_all, net::SocketAddr, process::Stdio};
use web::state::{SharedState, TemplateState}; use web::state::{SharedState, TemplateState};
use executor::executors_id; use executor::{executors, executors_id, Executor};
mod web; mod web;
pub mod executor; pub mod executor;
@ -21,10 +21,34 @@ fn check() {
if create_dir_all("/tmp/sandy-tmp").is_err() { if create_dir_all("/tmp/sandy-tmp").is_err() {
panic!("Cannot create temporary directory on /tmp/sandy-tmp"); panic!("Cannot create temporary directory on /tmp/sandy-tmp");
} }
let execs = executors();
let available = execs
.iter()
.map(|x| {
if ! x.available() {
log::warn!("{} is not available in this environment!", x.id())
}
x
})
.filter(|x| x.available())
.collect::<Vec<&Box<dyn Executor>>>()
.len();
if available == 0 {
panic!("No executors are available.");
}
} }
#[tokio::main] #[tokio::main]
async fn main() { async fn main() {
if cfg!(debug_assertions) {
femme::with_level(log::LevelFilter::Debug)
} else {
femme::with_level(log::LevelFilter::Info)
}
check(); check();
let state = SharedState { let state = SharedState {