feat: add sudo/doas

This commit is contained in:
DarkCat09 2025-03-26 15:12:58 +04:00
parent c54c836299
commit 6b0bc1ed38
Signed by: DarkCat09
SSH key fingerprint: SHA256:SnH1iYY/ogxxRmt1I6piy+aVUUzrOWvfksQWfhZ8JUM

View file

@ -1,6 +1,8 @@
use std::sync::Arc;
use ntex::{
http::StatusCode,
web::{self, App, HttpServer, Responder, WebResponseError},
web::{self, App, HttpServer, Responder, WebResponseError, types::State},
};
type Result<T> = core::result::Result<T, ErrorWrapper>;
@ -8,13 +10,18 @@ type Result<T> = core::result::Result<T, ErrorWrapper>;
#[ntex::main]
async fn main() -> std::io::Result<()> {
let bind = std::env::var("BIND").unwrap_or("127.0.0.1:5544".to_owned());
HttpServer::new(|| {
let cfg = Config {
doas: std::env::var("DOAS").map(Arc::new).ok(),
};
HttpServer::new(move || {
App::new()
.service(root)
.service(poweroff)
.service(ping)
.service(clients)
.service(temp)
.state(cfg.clone())
})
.bind(bind)?
.run()
@ -29,10 +36,19 @@ async fn root() -> impl Responder {
}
#[web::get("/off")]
async fn poweroff() -> Result<impl Responder> {
tokio::process::Command::new("/sbin/poweroff")
.kill_on_drop(false)
.spawn()?;
async fn poweroff(cfg: State<Config>) -> Result<impl Responder> {
const EXE: &str = "/sbin/poweroff";
let mut cmd = if let Some(doas) = &cfg.doas {
let mut cmd = tokio::process::Command::new(&**doas);
cmd.arg(EXE);
cmd
} else {
tokio::process::Command::new(EXE)
};
cmd.kill_on_drop(false).spawn()?;
Ok("OK")
}
@ -44,6 +60,7 @@ async fn ping() -> Result<impl Responder> {
.arg("1.1.1.1")
.output()
.await?;
Ok(format!(
"exited with {}\n\nstdout:\n{}\n----\n\nstderr:\n{}",
out.status,
@ -60,14 +77,27 @@ async fn clients() -> Result<impl Responder> {
}
#[web::get("/temp")]
async fn temp() -> Result<impl Responder> {
let out = tokio::process::Command::new("/usr/bin/vcgencmd")
.arg("measure_temp")
.output()
.await?;
async fn temp(cfg: State<Config>) -> Result<impl Responder> {
const EXE: &str = "/usr/bin/vcgencmd";
let mut cmd = if let Some(doas) = &cfg.doas {
let mut cmd = tokio::process::Command::new(&**doas);
cmd.arg(EXE);
cmd
} else {
tokio::process::Command::new(EXE)
};
let out = cmd.arg("measure_temp").output().await?;
Ok(String::from_utf8(out.stdout)?)
}
#[derive(Debug, Clone)]
struct Config {
doas: Option<Arc<String>>,
}
#[derive(Debug)]
struct ErrorWrapper(std::io::Error);