use axum::Extension; use axum::{extract::Path, response::IntoResponse, Json}; use axum_macros::debug_handler; use solarlib::ship::{DbShip, Ship}; use tokio::process::Command; use tracing::{error, instrument}; use solarlib::errors::Error as SolarlibError; use solarlib::planet::Planet; use solarlib::star::{NewPlanet, Star}; use crate::{errors::*, get_star, State}; use std::sync::Arc; pub async fn list() -> JsonResult>> { let con_url = std::env::var("QEMU_URL").unwrap_or("qemu:///system".to_string()); let mut star = Star::new(con_url)?; let inhabitants = star.inhabitants()?; Ok(Json(inhabitants)) } pub async fn get(Path(uuid): Path) -> JsonResult> { let con_url = std::env::var("QEMU_URL").unwrap_or("qemu:///system".to_string()); let mut star = Star::new(con_url)?; if let Ok(p) = star.find_planet(uuid) { return Ok(Json(p)); } else { return Err(ServiceError::NotFound); } } pub async fn shutdown(Path(uuid): Path) -> NoneResult { let con_url = std::env::var("QEMU_URL").unwrap_or("qemu:///system".to_string()); let mut star = Star::new(con_url)?; if let Ok(p) = star.find_planet(uuid) { p.shutdown()?; } else { return Err(ServiceError::NotFound); } Ok(()) } pub async fn start(Path(uuid): Path) -> NoneResult { let mut s = get_star()?; if let Ok(p) = s.find_planet(uuid) { p.start()?; } else { return Err(ServiceError::NotFound); } Ok(()) } pub async fn pause(Path(uuid): Path) -> NoneResult { let mut s = get_star()?; if let Ok(p) = s.find_planet(uuid) { p.pause()?; } else { return Err(ServiceError::NotFound); } Ok(()) } pub async fn reboot(Path(uuid): Path) -> NoneResult { let mut s = get_star()?; if let Ok(p) = s.find_planet(uuid) { p.reboot()?; } else { return Err(ServiceError::NotFound); } Ok(()) } pub async fn force_reboot(Path(uuid): Path) -> NoneResult { let mut s = get_star()?; if let Ok(p) = s.find_planet(uuid) { p.hard_reboot()?; } else { return Err(ServiceError::NotFound); } Ok(()) } pub async fn force_shutdown(Path(uuid): Path) -> NoneResult { let mut s = get_star()?; if let Ok(p) = s.find_planet(uuid) { p.hard_shutdown()?; } else { return Err(ServiceError::NotFound); } Ok(()) } #[debug_handler] pub async fn new_planet(Json(new_planet): Json) -> JsonResult> { let hw_url = std::env::var("HOMEWORLD_URL").unwrap(); let ship_shasum = new_planet.clone().ship; let res: DbShip = reqwest::get(format!("http://{}/ships/get/{}", hw_url, ship_shasum)) .await? .json() .await?; let ship: Ship = res.into(); let mut s = get_star()?; println!("{:?}", s); // Try to create right away, if the Ship already exists on the system, it'll go through. If // not, we can download it by using the shasum let r = s.planet( new_planet.clone().name, new_planet.max_mem, new_planet.max_cpus, new_planet.disk_size_mb, ship.clone(), Some(format!("http://{}", hw_url.clone())) ); match r { Err(e) => match e { SolarlibError::MissingImage(_) => { ship.download(&s)?; return Ok(Json(s.planet( new_planet.name, new_planet.max_mem, new_planet.max_cpus, new_planet.disk_size_mb, ship.clone(), Some(format!("http://{}", hw_url.clone())) )?)); } _ => { return Err(ServiceError::Solarlib(e)); } }, Ok(r) => { let tmp = s.inhabitants()?[0].clone(); return Ok(Json(tmp)); } }; } pub async fn no_planet(Path(uuid): Path) -> NoneResult { let mut s = get_star()?; if let Ok(p) = s.find_planet(uuid) { p.deathstar()?; } else { return Err(ServiceError::NotFound); } Ok(()) }