slight change

This commit is contained in:
2025-07-19 05:59:32 -05:00
parent 525e43441f
commit e0b749de16
3 changed files with 122 additions and 142 deletions
+26 -39
View File
@@ -101,27 +101,12 @@ pub fn save_apps(apps: &[App]) {
fs::write(path, json).expect("Failed to write apps.json"); fs::write(path, json).expect("Failed to write apps.json");
} }
pub fn uninstall_app(apps: &mut Vec<App>, id: &str) { pub fn uninstall_app(apps: &mut Vec<App>, index: usize) {
let id = { if index >= apps.len() {
let url = id.trim_end_matches(".git"); eprintln!("Invalid app index: {}", index);
return;
if url.starts_with("git@") {
// Format: [email protected]:usr/repo
url.split_once(':').map(|(_, path)| path.to_string())
} else if url.starts_with("https://") || url.starts_with("http://") {
// Format: https://github.com/usr/repo
url.split_once("github.com/")
.map(|(_, path)| path.to_string())
} else {
None
} }
}
.unwrap();
if let Some(index) = apps
.iter()
.position(|app| app.id().expect("Unable to obtain id") == id)
{
let app = &apps[index]; let app = &apps[index];
let repo_dir = apps_dir().join(app.repo_folder_name()); let repo_dir = apps_dir().join(app.repo_folder_name());
@@ -129,7 +114,7 @@ pub fn uninstall_app(apps: &mut Vec<App>, id: &str) {
if let Err(e) = fs::remove_dir_all(&repo_dir) { if let Err(e) = fs::remove_dir_all(&repo_dir) {
eprintln!("Failed to remove directory {:?}: {}", repo_dir, e); eprintln!("Failed to remove directory {:?}: {}", repo_dir, e);
} else { } else {
println!("Removed app: {}", id); println!("Removed app: {}", app.repo_folder_name());
} }
} }
@@ -150,9 +135,6 @@ pub fn uninstall_app(apps: &mut Vec<App>, id: &str) {
apps.remove(index); apps.remove(index);
save_apps(apps); save_apps(apps);
} else {
eprintln!("App not found: {}", id);
}
} }
pub fn install_app(apps: &mut Vec<App>, app: App) { pub fn install_app(apps: &mut Vec<App>, app: App) {
@@ -236,45 +218,50 @@ pub fn install_app(apps: &mut Vec<App>, app: App) {
save_apps(apps); save_apps(apps);
} }
pub fn toggle_app_state(id: &str, enable: bool) { pub fn toggle_app_state(apps: &[App], index: usize, enable: bool) {
if let Some(app) = apps.get(index) {
let id = app.id_system().expect("Unable to obtain id");
Command::new("systemctl") Command::new("systemctl")
.arg("--user") .arg("--user")
.arg(if enable { "enable" } else { "disable" }) .arg(if enable { "enable" } else { "disable" })
.arg(id) .arg(format!("{}.service", id))
.status() .status()
.expect("Failed to toggle app enable state"); .expect("Failed to toggle app state");
}
} }
pub fn start_app(id: &str) { pub fn start_app(apps: &[App], index: usize) {
if let Some(app) = apps.get(index) {
let id = app.id_system().expect("Unable to obtain id");
Command::new("systemctl") Command::new("systemctl")
.arg("--user") .arg("--user")
.arg("start") .arg("start")
.arg(id) .arg(format!("{}.service", id))
.status() .status()
.expect("Failed to start app"); .expect("Failed to start app");
} }
}
pub fn stop_app(id: &str) { pub fn stop_app(apps: &[App], index: usize) {
if let Some(app) = apps.get(index) {
let id = app.id_system().expect("Unable to obtain id");
Command::new("systemctl") Command::new("systemctl")
.arg("--user") .arg("--user")
.arg("stop") .arg("stop")
.arg(id) .arg(format!("{}.service", id))
.status() .status()
.expect("Failed to stop app"); .expect("Failed to stop app");
} }
}
pub fn restart_app(id: &str) { pub fn restart_app(apps: &[App], index: usize) {
if let Some(app) = apps.get(index) {
let id = app.id_system().expect("Unable to obtain id");
Command::new("systemctl") Command::new("systemctl")
.arg("--user")
.arg("restart") .arg("restart")
.arg(id) .arg(format!("{}.service", id))
.status() .status()
.expect("Failed to restart app"); .expect("Failed to restart app");
} }
pub fn get_app_by_id<'a>(apps: &'a [App], id: &str) -> Option<&'a App> {
apps.iter().find(|app| app.id() == Some(id.to_string()))
}
pub fn get_app_by_id_mut<'a>(apps: &'a mut [App], id: &str) -> Option<&'a mut App> {
apps.iter_mut().find(|app| app.id() == Some(id.to_string()))
} }
+39 -46
View File
@@ -1,7 +1,6 @@
pub mod app_manager; pub mod app_manager;
pub mod server_config; pub mod server_config;
use crate::app_manager::{get_app_by_id, get_app_by_id_mut, install_app, App};
use crate::server_config::ServerStats; use crate::server_config::ServerStats;
use std::sync::Arc; use std::sync::Arc;
use std::thread::spawn; use std::thread::spawn;
@@ -11,20 +10,22 @@ use tungstenite::accept;
#[derive(Debug, Clone, serde::Deserialize, serde::Serialize)] #[derive(Debug, Clone, serde::Deserialize, serde::Serialize)]
pub enum Method { pub enum Method {
Install(App), Install(app_manager::App),
SetEnabled(String, bool), Edit(usize, app_manager::App),
Edit(String, App), Uninstall(usize),
Uninstall(String), Toggle(usize, bool),
Toggle(String, bool), Start(usize),
Start(String), Stop(usize),
Stop(String), Restart(usize),
Restart(String),
} }
fn main() { fn main() {
println!("SentryX server starting...");
let apps = app_manager::init(); let apps = app_manager::init();
println!("Loaded {} apps", apps.len());
let server = TcpListener::bind("127.0.0.1:5273").unwrap(); let server = TcpListener::bind("0.0.0.0:5273").unwrap();
println!("Listening on 127.0.0.1:5273");
for stream in server.incoming() { for stream in server.incoming() {
let mut apps = apps.clone(); let mut apps = apps.clone();
@@ -32,6 +33,7 @@ fn main() {
let websocket = Arc::new(Mutex::new(accept(stream.unwrap()).unwrap())); let websocket = Arc::new(Mutex::new(accept(stream.unwrap()).unwrap()));
let reader_socket = Arc::clone(&websocket); let reader_socket = Arc::clone(&websocket);
let config = Arc::new(server_config::ServerConfig::new()); let config = Arc::new(server_config::ServerConfig::new());
println!("Client connected, awaiting master key...");
{ {
let master_key = reader_socket.lock().unwrap().read().unwrap(); let master_key = reader_socket.lock().unwrap().read().unwrap();
@@ -39,15 +41,17 @@ fn main() {
if !master_key.is_text() if !master_key.is_text()
|| master_key.to_text().unwrap() != config.master_key.clone() || master_key.to_text().unwrap() != config.master_key.clone()
{ {
println!("Invalid master key from client");
websocket websocket
.lock() .lock()
.unwrap() .unwrap()
.send(tungstenite::Message::text("!Invalid master key")) .send(tungstenite::Message::text("!Invalid master key"))
.unwrap(); .unwrap();
return; return;
} }
println!("Client authenticated successfully");
websocket websocket
.lock() .lock()
.unwrap() .unwrap()
@@ -67,52 +71,39 @@ fn main() {
) )
.unwrap(); .unwrap();
println!("Received command: {:?}", mth);
match mth { match mth {
Method::Install(app) => { Method::Install(app) => {
install_app(&mut apps, app); println!("→ Installing app: {}", app.repo);
} app_manager::install_app(&mut apps, app);
Method::SetEnabled(i, b) => {
let app = get_app_by_id_mut(&mut apps, &i).expect("App not found");
if let Some(id) = app.id_system() {
app_manager::toggle_app_state(&format!("{}.service", id), b);
}
app_manager::save_apps(&apps);
} }
Method::Edit(i, app) => { Method::Edit(i, app) => {
let existing_app = get_app_by_id_mut(&mut apps, &i).expect("App not found"); println!("→ Editing app at index {}: {}", i, app.repo);
if let Some(existing_app) = apps.get_mut(i) {
*existing_app = app; *existing_app = app;
app_manager::save_apps(&apps); app_manager::save_apps(&apps);
} }
Method::Uninstall(id) => {
app_manager::uninstall_app(&mut apps, &id);
} }
Method::Toggle(id, enable) => { Method::Uninstall(i) => {
let id = get_app_by_id(&mut apps, &id) println!("→ Uninstalling app at index {}", i);
.expect("App not found") app_manager::uninstall_app(&mut apps, i);
.id_system()
.unwrap();
app_manager::toggle_app_state(&format!("{}.service", id), enable);
} }
Method::Start(id) => { Method::Toggle(index, enable) => {
let id = get_app_by_id(&mut apps, &id) println!("→ Toggling app at index {} to {}", index, enable);
.expect("App not found") app_manager::toggle_app_state(&apps, index, enable);
.id_system()
.unwrap();
app_manager::start_app(&format!("{}.service", id));
} }
Method::Stop(id) => { Method::Start(index) => {
let id = get_app_by_id(&mut apps, &id) println!("→ Starting app at index {}", index);
.expect("App not found") app_manager::start_app(&apps, index);
.id_system()
.unwrap();
app_manager::stop_app(&format!("{}.service", id));
} }
Method::Restart(id) => { Method::Stop(index) => {
let id = get_app_by_id(&mut apps, &id) println!("→ Stopping app at index {}", index);
.expect("App not found") app_manager::stop_app(&apps, index);
.id_system() }
.unwrap(); Method::Restart(index) => {
app_manager::restart_app(&format!("{}.service", id)); println!("→ Restarting app at index {}", index);
app_manager::restart_app(&apps, index);
} }
} }
}); });
@@ -128,6 +119,7 @@ fn main() {
networks.refresh(true); networks.refresh(true);
disks.refresh(true); disks.refresh(true);
println!("→ Sending system stats update...");
websocket websocket
.lock() .lock()
.unwrap() .unwrap()
@@ -139,6 +131,7 @@ fn main() {
std::thread::sleep(std::time::Duration::from_secs(2)); std::thread::sleep(std::time::Duration::from_secs(2));
} }
println!("Client disconnected, cleaning up...");
}); });
} }
} }
+17 -17
View File
@@ -17,26 +17,26 @@ ws.onmessage = (msg) => console.log("Received:", msg.data);
ws.onopen = () => { ws.onopen = () => {
ws.send("my-key"); ws.send("my-key");
ws.send( // ws.send(
JSON.stringify({ // JSON.stringify({
Install: { // Install: {
repo: "[email protected]:osui-rs/osui.git", // repo: "[email protected]:osui-rs/osui.git",
branch: "master", // branch: "master",
install_command: "", // install_command: "",
run_command: "cargo run", // run_command: "cargo run",
} // }
}) // })
); // );
// ws.send(
// JSON.stringify({
// SetEnabled: ["osui-rs/osui", true]
// })
// );
ws.send( ws.send(
JSON.stringify({ JSON.stringify({
SetEnabled: ["osui-rs/osui", true] Start: 0
})
);
ws.send(
JSON.stringify({
Start: "osui-rs/osui"
}) })
); );