Better error handling and api testing
This commit is contained in:
parent
39394a8ff1
commit
7fe27c210c
|
|
@ -1206,7 +1206,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "rasp_mgr"
|
||||
version = "1.0.0"
|
||||
version = "2.0.2"
|
||||
dependencies = [
|
||||
"async-std",
|
||||
"clap",
|
||||
|
|
|
|||
|
|
@ -0,0 +1,33 @@
|
|||
GET http://0.0.0.0:8080/sysinfo
|
||||
|
||||
HTTP/1.1 200 - OK
|
||||
content-length: 788
|
||||
content-type: application/json
|
||||
date: Fri, 24 Dec 2021 16:01:32 GMT
|
||||
|
||||
###
|
||||
|
||||
GET http://0.0.0.0:8080/cmdquery
|
||||
|
||||
HTTP/1.1 200 - OK
|
||||
content-length: 179
|
||||
content-type: application/json
|
||||
date: Fri, 24 Dec 2021 15:58:24 GMT
|
||||
|
||||
###
|
||||
|
||||
GET http://0.0.0.0:8080/exec/lsblk
|
||||
|
||||
HTTP/1.1 200 - OK
|
||||
content-length: 533
|
||||
content-type: text/plain;charset=utf-8
|
||||
date: Fri, 24 Dec 2021 15:48:27 GMT
|
||||
|
||||
###
|
||||
|
||||
GET http://0.0.0.0:8080/exec/random
|
||||
|
||||
HTTP/1.1 400 - Bad Request
|
||||
content-length: 16
|
||||
content-type: text/plain;charset=utf-8
|
||||
date: Fri, 24 Dec 2021 15:57:38 GMT
|
||||
72
src/main.rs
72
src/main.rs
|
|
@ -14,8 +14,11 @@
|
|||
use std::{path::Path, process::Command};
|
||||
|
||||
use config::Config;
|
||||
use tide::{prelude::*, Request, Response, http::StatusCode, log::warn};
|
||||
use libmedium::{parse_hwmons,sensors::{Input, Sensor}};
|
||||
use libmedium::{
|
||||
parse_hwmons,
|
||||
sensors::{Input, Sensor},
|
||||
};
|
||||
use tide::{http::StatusCode, log::warn, prelude::*, utils::After, Request, Response};
|
||||
|
||||
mod config;
|
||||
mod disks;
|
||||
|
|
@ -36,20 +39,20 @@ struct SystemInfo {
|
|||
swap_total: f64,
|
||||
swap_used: f64,
|
||||
disk: Vec<Disk>,
|
||||
temperature: Vec<Temprature>
|
||||
temperature: Vec<Temprature>,
|
||||
}
|
||||
|
||||
#[derive(Serialize)]
|
||||
struct Disk {
|
||||
mount: String,
|
||||
total: f64,
|
||||
available: f64
|
||||
available: f64,
|
||||
}
|
||||
|
||||
#[derive(Serialize)]
|
||||
struct Temprature {
|
||||
label: String,
|
||||
temp: f64
|
||||
temp: f64,
|
||||
}
|
||||
|
||||
#[async_std::main]
|
||||
|
|
@ -59,11 +62,21 @@ async fn main() -> tide::Result<()> {
|
|||
tide::log::start();
|
||||
let mut app = tide::with_state(conf.clone());
|
||||
|
||||
app.with(After(|mut res: Response| async move {
|
||||
if let Some(err) = res.downcast_error::<&str>() {
|
||||
let err = err.to_owned();
|
||||
res.set_body(err);
|
||||
}
|
||||
Ok(res)
|
||||
}));
|
||||
|
||||
if let Some(val) = conf.static_dir {
|
||||
let path = Path::new(&val);
|
||||
if path.exists() && path.is_dir() {
|
||||
app.at("").serve_dir(path.to_str().unwrap())?;
|
||||
} else { warn!("Static Directory dosen't exists!") }
|
||||
} else {
|
||||
warn!("Static Directory dosen't exists!")
|
||||
}
|
||||
|
||||
let path = path.join("index.html");
|
||||
if path.exists() {
|
||||
|
|
@ -71,11 +84,11 @@ async fn main() -> tide::Result<()> {
|
|||
}
|
||||
}
|
||||
|
||||
app.at("/sysinfo").get(system_info);
|
||||
app.at("/cmdquery").get(cmd_query);
|
||||
app.at("/exec/:command").get(exec_cmd);
|
||||
app.at("/poweroff").get(poweroff);
|
||||
app.at("/reboot").get(reboot);
|
||||
app.at("/sysinfo").get(system_info);
|
||||
app.at("/cmdquery").get(cmd_query);
|
||||
app.listen(format!("{}:{}", conf.addr, conf.port)).await?;
|
||||
Ok(())
|
||||
}
|
||||
|
|
@ -83,7 +96,9 @@ async fn main() -> tide::Result<()> {
|
|||
async fn poweroff(_: Request<Config>) -> tide::Result {
|
||||
async_std::task::spawn(async {
|
||||
async_std::task::sleep(std::time::Duration::from_secs(3)).await;
|
||||
Command::new("poweroff").spawn().expect("Failed to poweroff!");
|
||||
Command::new("poweroff")
|
||||
.spawn()
|
||||
.expect("Failed to poweroff!");
|
||||
});
|
||||
Ok("Reqesting to poweroff. Please see green led for for activity".into())
|
||||
}
|
||||
|
|
@ -120,7 +135,7 @@ async fn system_info(_: Request<Config>) -> tide::Result {
|
|||
disk.push(Disk {
|
||||
mount: d.mount,
|
||||
total: d.total as f64 / 1048576.0, // bytes to mb
|
||||
available: d.available as f64 / 1048576.0 // bytes to mb
|
||||
available: d.available as f64 / 1048576.0, // bytes to mb
|
||||
});
|
||||
}
|
||||
|
||||
|
|
@ -131,15 +146,14 @@ async fn system_info(_: Request<Config>) -> tide::Result {
|
|||
let tmp = temp_sensor.read_input().unwrap();
|
||||
temperature.push(Temprature {
|
||||
label: temp_sensor.name(),
|
||||
temp: tmp.as_degrees_celsius()
|
||||
temp: tmp.as_degrees_celsius(),
|
||||
});
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
let boottime = std::time::Duration::from_secs(match sys_info::boottime() {
|
||||
Ok(s) => s.tv_sec as u64,
|
||||
Err(_) => 0
|
||||
Err(_) => 0,
|
||||
});
|
||||
|
||||
let sys_info = SystemInfo {
|
||||
|
|
@ -157,10 +171,15 @@ async fn system_info(_: Request<Config>) -> tide::Result {
|
|||
swap_total,
|
||||
swap_used,
|
||||
disk,
|
||||
temperature
|
||||
temperature,
|
||||
};
|
||||
|
||||
Ok(json!(sys_info).to_string().into())
|
||||
let body = tide::Body::from_json(&sys_info).map_err(|e| {
|
||||
tide::log::error!("Error: {}", e);
|
||||
tide::Error::from_str(StatusCode::ServiceUnavailable, "Internal server error!")
|
||||
})?;
|
||||
let res = Response::builder(StatusCode::Ok).body(body).build();
|
||||
Ok(res)
|
||||
}
|
||||
|
||||
fn last_update() -> Option<String> {
|
||||
|
|
@ -169,14 +188,15 @@ fn last_update() -> Option<String> {
|
|||
|
||||
let stdout = match cmd.output() {
|
||||
Ok(out) => out.stdout,
|
||||
Err(_) => return None
|
||||
Err(_) => return None,
|
||||
};
|
||||
|
||||
match String::from_utf8(stdout) {
|
||||
Ok(val) => {
|
||||
let s = val.split(" ").next()?;
|
||||
return Some(s[1..s.len()-1].to_owned());
|
||||
}, Err(_) => return None
|
||||
return Some(s[1..s.len() - 1].to_owned());
|
||||
}
|
||||
Err(_) => return None,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -189,19 +209,21 @@ fn exec(cmd: &mut Command) -> String {
|
|||
|
||||
match String::from_utf8(out.unwrap().stdout) {
|
||||
Ok(out) => return out,
|
||||
Err(_) => return "Request timeout".to_owned()
|
||||
Err(_) => return "Request timeout".to_owned(),
|
||||
}
|
||||
}
|
||||
|
||||
async fn exec_cmd(req: Request<Config>) -> tide::Result {
|
||||
let cmd = req.state().commands.get(
|
||||
req.param("command").map_err(|e| {
|
||||
let cmd = req
|
||||
.state()
|
||||
.commands
|
||||
.get(req.param("command").map_err(|e| {
|
||||
tide::log::error!("Error: {}", e);
|
||||
tide::Error::from_str(StatusCode::BadRequest, "Invalid Request!")
|
||||
})?
|
||||
).ok_or_else(|| {
|
||||
tide::Error::from_str(StatusCode::BadRequest, "No such command!")
|
||||
})?.command.as_str();
|
||||
})?)
|
||||
.ok_or_else(|| tide::Error::from_str(StatusCode::BadRequest, "No such command!"))?
|
||||
.command
|
||||
.as_str();
|
||||
let args: Vec<_> = cmd.split_ascii_whitespace().collect();
|
||||
Ok(exec(Command::new(&args[0]).args(&args[1..])).into())
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue