From 85bd8eb18c6c01157571b7612a58a6d488e744f7 Mon Sep 17 00:00:00 2001 From: stubbfelnewpc Date: Sat, 27 Jun 2020 18:59:47 +0200 Subject: [PATCH] split up in severals libs --- Cargo.lock | 20 +++ Cargo.toml | 2 +- server/cli/Cargo.toml | 8 +- server/cli/src/main.rs | 292 ++------------------------------------- server/lib/Cargo.toml | 17 +++ server/lib/src/lib.rs | 235 +++++++++++++++++++++++++++++++ server/podman/Cargo.toml | 13 ++ server/podman/src/lib.rs | 71 ++++++++++ 8 files changed, 370 insertions(+), 288 deletions(-) create mode 100644 server/lib/Cargo.toml create mode 100644 server/lib/src/lib.rs create mode 100644 server/podman/Cargo.toml create mode 100644 server/podman/src/lib.rs diff --git a/Cargo.lock b/Cargo.lock index b31c979..de4f768 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -682,6 +682,16 @@ dependencies = [ [[package]] name = "nixideserver_cli" version = "0.1.0" +dependencies = [ + "nixideserver_lib", + "okapi", + "rocket", + "rocket_okapi", +] + +[[package]] +name = "nixideserver_lib" +version = "0.1.0" dependencies = [ "okapi", "rocket", @@ -693,6 +703,16 @@ dependencies = [ "serde_json", ] +[[package]] +name = "nixideserver_podman_lib" +version = "0.1.0" +dependencies = [ + "nixideserver_lib", + "rocket", + "serde", + "serde_derive", +] + [[package]] name = "notify" version = "4.0.15" diff --git a/Cargo.toml b/Cargo.toml index 4d50675..ad32c2c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,2 +1,2 @@ [workspace] -members = ["control/cli", "server/cli"] \ No newline at end of file +members = ["control/cli", "server/cli", "server/lib", "server/podman"] \ No newline at end of file diff --git a/server/cli/Cargo.toml b/server/cli/Cargo.toml index 35a9ee0..81287bc 100644 --- a/server/cli/Cargo.toml +++ b/server/cli/Cargo.toml @@ -8,10 +8,6 @@ edition = "2018" [dependencies] rocket = "0.4.5" -rocket_contrib = "0.4.5" -serde = "1.0" -serde_json = "1.0" -serde_derive = "1.0" rocket_okapi = "0.5.1" -schemars = "0.7.6" -okapi = "0.4.0" \ No newline at end of file +okapi = "0.4.0" +nixideserver_lib = { path = "../lib"} \ No newline at end of file diff --git a/server/cli/src/main.rs b/server/cli/src/main.rs index 6f29ff9..f70a1ef 100644 --- a/server/cli/src/main.rs +++ b/server/cli/src/main.rs @@ -1,295 +1,25 @@ #![feature(proc_macro_hygiene, decl_macro)] -#[macro_use] extern crate rocket; -#[macro_use] extern crate serde_derive; +extern crate rocket; #[macro_use] extern crate rocket_okapi; +extern crate okapi; +extern crate nixideserver_lib; -use schemars::JsonSchema; use rocket_okapi::{ - response::OpenApiResponder, - gen::OpenApiGenerator, swagger_ui::*, }; -use rocket::{ - http::{ - hyper::header::Location, - Status - }, - State, - Response, - response::status, - request::Request, - response::Responder -}; -use okapi::openapi3::Responses; -use rocket_contrib::json::{Json}; -use std::collections::hash_map::DefaultHasher; -use std::hash::{ - Hash, - Hasher -}; - // podman create --name test -p 3000:3000 -v $PWD:/nixide -w /nixide docker.io/nixos/nix nix-shell --pure start-ide.nix --run run_ide.sh - - #[derive(Serialize, Deserialize, Hash, JsonSchema)] - pub enum IdeState - { - UNKOWN, - OPENING, - OPENED, - CLOSING, - CLOSED, - DELETING, - DELETED - } - -#[derive(Serialize, Deserialize, Hash, JsonSchema)] -pub struct OpenGitParam -{ - inquirer: String, - clone_url: String, - ref_name: String -} - -#[derive(Serialize, Deserialize, Hash, JsonSchema)] -pub struct IdeStateResponse -{ - ide_id: String, - state: IdeState -} - -pub trait NixIdeManageServiceEngine { - fn fetch_current_ide_state(&self, ide_id : &str) -> Result; - fn start_open(&self, ide_id : &str, param : &OpenGitParam) -> Result; -} - -pub struct NixIdeManageService { - eng :Box -} - -unsafe impl Send for NixIdeManageService {} -unsafe impl Sync for NixIdeManageService {} - -struct DummyEngine{} - -impl NixIdeManageServiceEngine for DummyEngine { - fn fetch_current_ide_state(&self, _ide_id : &str) -> Result { - Ok(IdeState::OPENING) - } - - fn start_open(&self, _ide_id : &str, _param : &OpenGitParam) -> Result - { - Ok(IdeState::OPENING) - } -} - -struct PodmanEngine{} - -impl NixIdeManageServiceEngine for PodmanEngine { - fn fetch_current_ide_state(&self, _ide_id : &str) -> Result { - Ok(IdeState::OPENING) - } - - fn start_open(&self, _ide_id : &str, _param : &OpenGitParam) -> Result{ - Ok(IdeState::OPENING) - } -} - -#[derive(Serialize, Deserialize, Hash)] -pub struct NixIdeServerParam { - #[serde(default = "default_listen_address")] - listen_address: String, - #[serde(default = "default_listen_port")] - listen_port: u32, - #[serde(default = "default_app_folder")] - app_folder: String, - #[serde(default = "default_project_folder")] - project_folder: String, - #[serde(default = "default_working_folder")] - working_folder: String -} - -fn default_listen_address() -> String { - "0.0.0.0".to_owned() -} - -fn default_listen_port() -> u32 { - 3000 -} - -fn default_app_folder() -> String { - "_theiaideApp".to_owned() -} - -fn default_project_folder() -> String { - "$PWD".to_owned() -} - -fn default_working_folder() -> String { - "$PWD".to_owned() -} - -pub struct LocationHeader(pub Option, pub Location); - -/// Sets the status code of the response to 202 Accepted. If the responder is -/// `Some`, it is used to finalize the response. -impl<'r, R: Responder<'r>> Responder<'r> for LocationHeader { - fn respond_to(self, req: &Request) -> Result, Status> { - let mut build = Response::build(); - if let Some(responder) = self.0 { - build.merge(responder.respond_to(req)?); - } - - build.header(self.1).ok() - } -} - -pub type Map = schemars::Map; -type Object = Map; - -impl<'r, T: OpenApiResponder<'r>> OpenApiResponder<'r> for LocationHeader { - fn responses(gen: &mut OpenApiGenerator) -> rocket_okapi::Result { - let mut responses = T::responses(gen)?; - let mut rep = okapi::openapi3::Response::default(); - let header = okapi::openapi3::Header{ - description: Some("foo".to_owned()), - required: true, - deprecated: false, - allow_empty_value: false, - value: okapi::openapi3::ParameterValue::Schema { - style: None, - explode: None, - allow_reserved: false, - schema: schemars::schema::SchemaObject::default(), - example: None, - examples: None, - }, - extensions: Object::default(), - }; - rep.headers.insert("Location".to_owned(), okapi::openapi3::RefOr::Object(header)); - responses.responses.insert(String::new(), okapi::openapi3::RefOr::Object(rep)); - Ok(responses) - } -} - -#[derive(Debug)] -struct Error {} - - -#[openapi] -#[get("/open//git?&")] -fn v1_open_inquirer_git(inquirer: String, clone_url: String, ref_name: String, srv : State) -> Result>, Error> { - let param = OpenGitParam { - inquirer, - clone_url, - ref_name - }; - - let mut s = DefaultHasher::new(); - param.hash(&mut s); - let hash = s.finish(); - - // println!("foo {:x}", hash); - // let out = Command::new("podman") - // .arg("create") - // .arg("--name") - // .arg(format!("{:x}", hash)) - // .arg("-p") - // .arg("3000:3000") - // .arg("docker.io/nixos/nix") - // // .arg(format!("git clone {}", param.clone_url)) - // .output() - // .expect("create container"); - // String::from_utf8(out.stderr).unwrap() - - let ide_id = format!("{:x}", hash); - srv.eng.start_open(&ide_id, ¶m).map_err(|_| {Error {}}).and_then(|starting_result| { - Ok( - status::Accepted ( - Some( - Json( - IdeStateResponse { - ide_id : ide_id, - state : starting_result - } - ) - ) - ) - ) - }) - -} - -#[openapi] -#[get("/state/")] -fn v1_ide_state(ide_ide: String, srv : State) -> Json -{ - srv.eng.fetch_current_ide_state(&ide_ide).and_then(|ide_state| { - Ok( - Json( - IdeStateResponse{ - ide_id: ide_ide, - state : ide_state - } - ) - ) - }).unwrap() -} - -#[openapi] -#[get("/open//gitea?&")] -fn v1_open_inquirer_gitea(inquirer: String, clone_url: String, ref_name: String) -> status::Accepted> { - let param = OpenGitParam { - inquirer, - clone_url, - ref_name - }; - status::Accepted(Some(Json(param))) -} - -#[openapi] -#[get("/open//gitlab?&")] -fn v1_open_inquirer_gitlab(inquirer: String, clone_url: String, ref_name: String) -> status::Accepted> { - let param = OpenGitParam { - inquirer, - clone_url, - ref_name - }; - status::Accepted(Some(Json(param))) -} - -#[openapi] -#[get("/open//github?&")] -fn v1_open_inquirer_github(inquirer: String, clone_url: String, ref_name: String) -> status::Accepted> { - let param = OpenGitParam { - inquirer, - clone_url, - ref_name - }; - status::Accepted(Some(Json(param))) -} - -#[openapi] -#[get("/open/gitlab?&")] -fn v1_open_gitlab(clone_url: String, ref_name: String) -> status::Accepted> { - let param = OpenGitParam { - inquirer : "foo".to_owned(), - clone_url, - ref_name - }; - status::Accepted(Some(Json(param))) -} - -fn main() { +use nixideserver_lib::*; +fn main() { let eng = DummyEngine{}; - let exectuor = NixIdeManageService{eng:Box::new(eng)}; + let exectuor = NixIdeManageService::new(Box::new(eng)); rocket::ignite() .mount("/api/v1/", routes_with_openapi![ v1_open_inquirer_git, - v1_open_inquirer_gitea, - v1_open_gitlab, - v1_open_inquirer_github, - v1_open_inquirer_gitlab, - v1_ide_state + v1_open_inquirer_gitea, + v1_open_gitlab, + v1_open_inquirer_github, + v1_open_inquirer_gitlab, + v1_ide_state ]) .manage(exectuor) .mount( diff --git a/server/lib/Cargo.toml b/server/lib/Cargo.toml new file mode 100644 index 0000000..2f798ce --- /dev/null +++ b/server/lib/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "nixideserver_lib" +version = "0.1.0" +authors = ["stubbfelnewpc "] +edition = "2018" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +rocket = "0.4.5" +rocket_contrib = "0.4.5" +serde = "1.0" +serde_json = "1.0" +serde_derive = "1.0" +rocket_okapi = "0.5.1" +schemars = "0.7.6" +okapi = "0.4.0" \ No newline at end of file diff --git a/server/lib/src/lib.rs b/server/lib/src/lib.rs new file mode 100644 index 0000000..1964488 --- /dev/null +++ b/server/lib/src/lib.rs @@ -0,0 +1,235 @@ +#![feature(proc_macro_hygiene, decl_macro)] +#[macro_use] extern crate rocket; +#[macro_use] extern crate serde_derive; +#[macro_use] extern crate rocket_okapi; +extern crate serde; +extern crate serde_json; +extern crate schemars; +extern crate okapi; + +use schemars::JsonSchema; +use rocket_okapi::{ + response::OpenApiResponder, + gen::OpenApiGenerator, +}; +use rocket::{ + http::{ + hyper::header::Location, + Status + }, + State, + Response, + response::status, + request::Request, + response::Responder +}; +use okapi::openapi3::Responses; +use rocket_contrib::json::{Json}; +use std::collections::hash_map::DefaultHasher; +use std::hash::{ + Hash, + Hasher +}; + + #[derive(Serialize, Deserialize, Hash, JsonSchema, Clone)] + pub enum IdeState + { + UNKOWN, + OPENING, + OPENED, + CLOSING, + CLOSED, + DELETING, + DELETED + } + +#[derive(Serialize, Deserialize, Hash, JsonSchema)] +pub struct OpenGitParam +{ + inquirer: String, + clone_url: String, + ref_name: String +} + +#[derive(Serialize, Deserialize, Hash, JsonSchema)] +pub struct IdeStateResponse +{ + ide_id: String, + state: IdeState, + href: Option +} + +pub trait NixIdeManageServiceEngine { + fn fetch_current_ide_state(&self, ide_id : &str) -> Result; + fn start_open(&self, ide_id : &str, param : &OpenGitParam) -> Result; +} + +pub struct NixIdeManageService { + eng :Box +} +impl NixIdeManageService { + pub fn new(engine : Box) -> Self + { + Self { + eng : engine + } + } +} + +unsafe impl Send for NixIdeManageService {} +unsafe impl Sync for NixIdeManageService {} + +pub struct DummyEngine{} + +impl NixIdeManageServiceEngine for DummyEngine { + fn fetch_current_ide_state(&self, _ide_id : &str) -> Result { + Ok(IdeState::OPENING) + } + + fn start_open(&self, _ide_id : &str, _param : &OpenGitParam) -> Result + { + Ok(IdeState::OPENING) + } +} + +pub struct LocationHeader(pub Option, pub Location); + +/// Sets the status code of the response to 202 Accepted. If the responder is +/// `Some`, it is used to finalize the response. +impl<'r, R: Responder<'r>> Responder<'r> for LocationHeader { + fn respond_to(self, req: &Request) -> Result, Status> { + let mut build = Response::build(); + if let Some(responder) = self.0 { + build.merge(responder.respond_to(req)?); + } + + build.header(self.1).ok() + } +} + +pub type Map = schemars::Map; +type Object = Map; + +impl<'r, T: OpenApiResponder<'r>> OpenApiResponder<'r> for LocationHeader { + fn responses(gen: &mut OpenApiGenerator) -> rocket_okapi::Result { + let mut responses = T::responses(gen)?; + let mut rep = okapi::openapi3::Response::default(); + let header = okapi::openapi3::Header{ + description: Some("Location Header".to_owned()), + required: true, + deprecated: false, + allow_empty_value: false, + value: okapi::openapi3::ParameterValue::Schema { + style: None, + explode: None, + allow_reserved: false, + schema: schemars::schema::SchemaObject::default(), + example: None, + examples: None, + }, + extensions: Object::default(), + }; + rep.headers.insert("Location".to_owned(), okapi::openapi3::RefOr::Object(header)); + responses.responses.insert(String::new(), okapi::openapi3::RefOr::Object(rep)); + Ok(responses) + } +} + +#[derive(Debug)] +pub struct Error {} + + +#[openapi] +#[get("/open//git?&")] +pub fn v1_open_inquirer_git(inquirer: String, clone_url: String, ref_name: String, srv : State) -> Result>, Error> { + let param = OpenGitParam { + inquirer, + clone_url, + ref_name + }; + + let mut s = DefaultHasher::new(); + param.hash(&mut s); + let hash = s.finish(); + + let ide_id = format!("{:x}", hash); + srv.eng.start_open(&ide_id, ¶m).map_err(|_| {Error {}}).and_then(|starting_result| { + Ok( + status::Accepted ( + Some( + Json( + IdeStateResponse { + state : starting_result, + href: Some(format!("/api/v1/state/{}", ide_id)), + ide_id : ide_id + } + ) + ) + ) + ) + }) +} + +#[openapi] +#[get("/state/")] +pub fn v1_ide_state(ide_id: String, srv : State) -> Result, status::NotFound> +{ + srv.eng.fetch_current_ide_state(&ide_id).and_then(|ide_state| { + Ok( + Json( + IdeStateResponse{ + href: Some(match &ide_state { + IdeState::OPENED => format!("/xxx/{}", ide_id), + _ => format!("/api/v1/state/{}", ide_id) + }), + ide_id: ide_id, + state : ide_state + } + ) + ) + }).map_err(|_| status::NotFound("Sorry, I couldn't find it!".to_owned())) +} + +#[openapi] +#[get("/open//gitea?&")] +pub fn v1_open_inquirer_gitea(inquirer: String, clone_url: String, ref_name: String) -> status::Accepted> { + let param = OpenGitParam { + inquirer, + clone_url, + ref_name + }; + status::Accepted(Some(Json(param))) +} + +#[openapi] +#[get("/open//gitlab?&")] +pub fn v1_open_inquirer_gitlab(inquirer: String, clone_url: String, ref_name: String) -> status::Accepted> { + let param = OpenGitParam { + inquirer, + clone_url, + ref_name + }; + status::Accepted(Some(Json(param))) +} + +#[openapi] +#[get("/open//github?&")] +pub fn v1_open_inquirer_github(inquirer: String, clone_url: String, ref_name: String) -> status::Accepted> { + let param = OpenGitParam { + inquirer, + clone_url, + ref_name + }; + status::Accepted(Some(Json(param))) +} + +#[openapi] +#[get("/open/gitlab?&")] +pub fn v1_open_gitlab(clone_url: String, ref_name: String) -> status::Accepted> { + let param = OpenGitParam { + inquirer : "foo".to_owned(), + clone_url, + ref_name + }; + status::Accepted(Some(Json(param))) +} diff --git a/server/podman/Cargo.toml b/server/podman/Cargo.toml new file mode 100644 index 0000000..5f8146b --- /dev/null +++ b/server/podman/Cargo.toml @@ -0,0 +1,13 @@ +[package] +name = "nixideserver_podman_lib" +version = "0.1.0" +authors = ["stubbfelnewpc "] +edition = "2018" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +rocket = "0.4.5" +serde = "1.0" +serde_derive = "1.0" +nixideserver_lib = { path = "../lib"} \ No newline at end of file diff --git a/server/podman/src/lib.rs b/server/podman/src/lib.rs new file mode 100644 index 0000000..75622cd --- /dev/null +++ b/server/podman/src/lib.rs @@ -0,0 +1,71 @@ +#![feature(proc_macro_hygiene, decl_macro)] + extern crate rocket; + extern crate serde; +#[macro_use] extern crate serde_derive; +extern crate nixideserver_lib; + +use rocket::http::Status; +use std::hash::Hash; +use nixideserver_lib::*; + + // podman create --name test -p 3000:3000 -v $PWD:/nixide -w /nixide docker.io/nixos/nix nix-shell --pure start-ide.nix --run run_ide.sh + +pub struct PodmanEngine{} + +impl NixIdeManageServiceEngine for PodmanEngine { + fn fetch_current_ide_state(&self, _ide_id : &str) -> Result { + Ok(IdeState::OPENING) + } + + fn start_open(&self, _ide_id : &str, _param : &OpenGitParam) -> Result { + + // println!("foo {:x}", hash); + // let out = Command::new("podman") + // .arg("create") + // .arg("--name") + // .arg(format!("{:x}", hash)) + // .arg("-p") + // .arg("3000:3000") + // .arg("docker.io/nixos/nix") + // // .arg(format!("git clone {}", param.clone_url)) + // .output() + // .expect("create container"); + // String::from_utf8(out.stderr).unwrap() + + Ok(IdeState::OPENING) + } +} + +#[derive(Serialize, Deserialize, Hash)] +pub struct NixIdeServerParam { + #[serde(default = "default_listen_address")] + listen_address: String, + #[serde(default = "default_listen_port")] + listen_port: u32, + #[serde(default = "default_app_folder")] + app_folder: String, + #[serde(default = "default_project_folder")] + project_folder: String, + #[serde(default = "default_working_folder")] + working_folder: String +} + +fn default_listen_address() -> String { + "0.0.0.0".to_owned() +} + +fn default_listen_port() -> u32 { + 3000 +} + +fn default_app_folder() -> String { + "_theiaideApp".to_owned() +} + +fn default_project_folder() -> String { + "$PWD".to_owned() +} + +fn default_working_folder() -> String { + "$PWD".to_owned() +}