aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorCara Salter <cara@devcara.com>2022-06-10 14:40:56 -0400
committerCara Salter <cara@devcara.com>2022-06-10 14:40:56 -0400
commit4c044c28559f356883e4ab3cec437bbb20ce7f89 (patch)
treee8f697b87a56726689088c2127aba297276e3ffe /src
parentf64edeb631bfdefcd757483d7dfbe204daabf1ab (diff)
downloadsolard-4c044c28559f356883e4ab3cec437bbb20ce7f89.tar.gz
solard-4c044c28559f356883e4ab3cec437bbb20ce7f89.zip
planets: Create new planets
Star systems in the palm of your keyboard!
Diffstat (limited to 'src')
-rw-r--r--src/errors.rs6
-rw-r--r--src/handlers/planets.rs58
-rw-r--r--src/main.rs15
3 files changed, 75 insertions, 4 deletions
diff --git a/src/errors.rs b/src/errors.rs
index b22932f..e0a6df9 100644
--- a/src/errors.rs
+++ b/src/errors.rs
@@ -15,6 +15,12 @@ pub enum ServiceError {
#[error("Not Found")]
NotFound,
+
+ #[error("Reqwest: {0}")]
+ Reqwest(#[from] reqwest::Error),
+
+ #[error("Command error: {0}")]
+ Command(#[from] std::io::Error)
}
pub type StringResult<T = &'static str> = std::result::Result<T, ServiceError>;
diff --git a/src/handlers/planets.rs b/src/handlers/planets.rs
index 06773bc..2c66324 100644
--- a/src/handlers/planets.rs
+++ b/src/handlers/planets.rs
@@ -1,11 +1,17 @@
+use axum::Extension;
+use axum_macros::debug_handler;
use axum::{response::IntoResponse, Json, extract::Path};
+use solarlib::ship::{DbShip, Ship};
+use tokio::process::Command;
use tracing::{error, instrument};
-use solarlib::star::Star;
+use solarlib::star::{Star, NewPlanet};
use solarlib::planet::Planet;
+use solarlib::errors::Error as SolarlibError;
-use crate::{errors::*, get_star};
+use crate::{errors::*, get_star, State};
+use std::sync::Arc;
pub async fn list() -> JsonResult<Json<Vec<Planet>>> {
let con_url = std::env::var("QEMU_URL").unwrap_or("qemu:///system".to_string());
@@ -100,3 +106,51 @@ pub async fn force_shutdown(Path(uuid): Path<String>) -> NoneResult {
Ok(())
}
+
+#[debug_handler]
+pub async fn new_planet(Json(new_planet): Json<NewPlanet>) -> JsonResult<Json<Planet>> {
+ 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());
+ 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())?));
+ },
+ _ => {
+ 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<String>) -> NoneResult {
+ let mut s = get_star()?;
+
+ if let Ok(p) = s.find_planet(uuid) {
+ p.deathstar()?;
+ } else {
+ return Err(ServiceError::NotFound);
+ }
+
+ Ok(())
+}
diff --git a/src/main.rs b/src/main.rs
index c235d41..4dc78a6 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -4,12 +4,12 @@ use axum::{
response::IntoResponse,
routing::{get, post},
handler::Handler,
- Json, Router
+ Json, Router, Extension
};
use serde::{Deserialize, Serialize};
use solarlib::star::Star;
-use std::{net::SocketAddr, time::Duration, str::FromStr};
+use std::{net::SocketAddr, time::Duration, str::FromStr, sync::Arc};
use tower::{BoxError, ServiceBuilder};
use tower_http::trace::TraceLayer;
@@ -20,6 +20,10 @@ mod errors;
mod handlers;
+pub struct State {
+ pub hw_url: String,
+}
+
#[tokio::main]
async fn main() {
kankyo::init();
@@ -32,9 +36,14 @@ async fn main() {
.with(tracing_subscriber::fmt::layer())
.init();
+ let shared_state = Arc::new(State {
+ hw_url: std::env::var("HOMEWORLD_URL").expect("No Homeworld URL set"),
+ });
+
let app = Router::new()
.route("/health", get(health_check))
.route("/planets/list", get(handlers::planets::list))
+ .route("/planets/new", post(handlers::planets::new_planet))
.route("/planets/:uuid", get(handlers::planets::get))
.route("/planets/:uuid/shutdown", post(handlers::planets::shutdown))
.route("/planets/:uuid/shutdown/hard", post(handlers::planets::force_shutdown))
@@ -42,6 +51,7 @@ async fn main() {
.route("/planets/:uuid/pause", post(handlers::planets::pause))
.route("/planets/:uuid/reboot", post(handlers::planets::reboot))
.route("/planets/:uuid/reboot/hard", post(handlers::planets::force_reboot))
+ .route("/planets/:uuid/destroy", post(handlers::planets::no_planet))
.layer( ServiceBuilder::new()
.layer(HandleErrorLayer::new(|error: BoxError| async move {
if error.is::<tower::timeout::error::Elapsed>() {
@@ -57,6 +67,7 @@ async fn main() {
.layer(TraceLayer::new_for_http())
.into_inner(),
)
+ .layer(Extension(shared_state))
.fallback(handler_404.into_service());
let addr = SocketAddr::from_str(std::env::var("BIND_ADDR").unwrap().as_str().into()).unwrap();