From ee1a48a28e2b7aebe6b8d18574b90e000748a10d Mon Sep 17 00:00:00 2001 From: stubbfelnewpc Date: Sat, 27 Jun 2020 20:31:03 +0200 Subject: [PATCH] podman engine setp ide folder --- Cargo.lock | 2 + server/cli/Cargo.toml | 3 +- server/cli/src/main.rs | 34 ++++--- server/lib/src/lib.rs | 213 ++++++++++++++++++++------------------- server/podman/Cargo.toml | 1 + server/podman/src/lib.rs | 83 ++++++++++----- 6 files changed, 192 insertions(+), 144 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index de4f768..864eccb 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -684,6 +684,7 @@ name = "nixideserver_cli" version = "0.1.0" dependencies = [ "nixideserver_lib", + "nixideserver_podman_lib", "okapi", "rocket", "rocket_okapi", @@ -711,6 +712,7 @@ dependencies = [ "rocket", "serde", "serde_derive", + "serde_json", ] [[package]] diff --git a/server/cli/Cargo.toml b/server/cli/Cargo.toml index 81287bc..8f22996 100644 --- a/server/cli/Cargo.toml +++ b/server/cli/Cargo.toml @@ -10,4 +10,5 @@ edition = "2018" rocket = "0.4.5" rocket_okapi = "0.5.1" okapi = "0.4.0" -nixideserver_lib = { path = "../lib"} \ No newline at end of file +nixideserver_lib = { path = "../lib"} +nixideserver_podman_lib = {path = "../podman"} \ No newline at end of file diff --git a/server/cli/src/main.rs b/server/cli/src/main.rs index f70a1ef..900d50b 100644 --- a/server/cli/src/main.rs +++ b/server/cli/src/main.rs @@ -1,26 +1,32 @@ #![feature(proc_macro_hygiene, decl_macro)] extern crate rocket; -#[macro_use] extern crate rocket_okapi; -extern crate okapi; +#[macro_use] +extern crate rocket_okapi; extern crate nixideserver_lib; +extern crate nixideserver_podman_lib; +extern crate okapi; -use rocket_okapi::{ - swagger_ui::*, -}; +use nixideserver_podman_lib::PodmanEngine; +use rocket_okapi::swagger_ui::*; +use std::env; use nixideserver_lib::*; fn main() { - let eng = DummyEngine{}; + let eng = DummyEngine {}; + let _podman_eng = PodmanEngine::new(env::current_dir().unwrap()); 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 - ]) + .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 + ], + ) .manage(exectuor) .mount( "/swagger-ui/", diff --git a/server/lib/src/lib.rs b/server/lib/src/lib.rs index 1964488..b210f99 100644 --- a/server/lib/src/lib.rs +++ b/server/lib/src/lib.rs @@ -1,93 +1,79 @@ #![feature(proc_macro_hygiene, decl_macro)] -#[macro_use] extern crate rocket; -#[macro_use] extern crate serde_derive; -#[macro_use] extern crate rocket_okapi; +#[macro_use] +extern crate rocket; +#[macro_use] +extern crate serde_derive; +#[macro_use] +extern crate rocket_okapi; +extern crate okapi; +extern crate schemars; 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 +use rocket::{ + http::{hyper::header::Location, Status}, + request::Request, + response::status, + response::Responder, + Response, State, }; +use rocket_contrib::json::Json; +use rocket_okapi::{gen::OpenApiGenerator, response::OpenApiResponder}; +use schemars::JsonSchema; +use std::collections::hash_map::DefaultHasher; +use std::hash::{Hash, Hasher}; - #[derive(Serialize, Deserialize, Hash, JsonSchema, Clone)] - pub enum IdeState - { +#[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 + DELETED, } #[derive(Serialize, Deserialize, Hash, JsonSchema)] -pub struct IdeStateResponse -{ +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 + 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; + 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 + eng: Box, } impl NixIdeManageService { - pub fn new(engine : Box) -> Self - { - Self { - eng : engine - } + pub fn new(engine: Box) -> Self { + Self { eng: engine } } } unsafe impl Send for NixIdeManageService {} unsafe impl Sync for NixIdeManageService {} -pub struct DummyEngine{} +pub struct DummyEngine {} impl NixIdeManageServiceEngine for DummyEngine { - fn fetch_current_ide_state(&self, _ide_id : &str) -> Result { + fn fetch_current_ide_state(&self, _ide_id: &str) -> Result { Ok(IdeState::OPENING) } - fn start_open(&self, _ide_id : &str, _param : &OpenGitParam) -> Result - { + fn start_open(&self, _ide_id: &str, _param: &OpenGitParam) -> Result { Ok(IdeState::OPENING) } } @@ -114,12 +100,12 @@ 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{ + let header = okapi::openapi3::Header { description: Some("Location Header".to_owned()), required: true, deprecated: false, allow_empty_value: false, - value: okapi::openapi3::ParameterValue::Schema { + value: okapi::openapi3::ParameterValue::Schema { style: None, explode: None, allow_reserved: false, @@ -129,8 +115,13 @@ impl<'r, T: OpenApiResponder<'r>> OpenApiResponder<'r> for LocationHeader { }, extensions: Object::default(), }; - rep.headers.insert("Location".to_owned(), okapi::openapi3::RefOr::Object(header)); - responses.responses.insert(String::new(), okapi::openapi3::RefOr::Object(rep)); + rep.headers.insert( + "Location".to_owned(), + okapi::openapi3::RefOr::Object(header), + ); + responses + .responses + .insert(String::new(), okapi::openapi3::RefOr::Object(rep)); Ok(responses) } } @@ -138,87 +129,96 @@ impl<'r, T: OpenApiResponder<'r>> OpenApiResponder<'r> for LocationHeader { #[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> { +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 + ref_name, }; - let mut s = DefaultHasher::new(); - param.hash(&mut s); - let hash = s.finish(); + let ide_id = create_ide_id(¶m); - 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 - } - ) - ) - ) - ) - }) + 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())) +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> { +pub fn v1_open_inquirer_gitea( + inquirer: String, + clone_url: String, + ref_name: String, +) -> status::Accepted> { let param = OpenGitParam { inquirer, clone_url, - ref_name + 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> { +pub fn v1_open_inquirer_gitlab( + inquirer: String, + clone_url: String, + ref_name: String, +) -> status::Accepted> { let param = OpenGitParam { inquirer, clone_url, - ref_name + 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> { +pub fn v1_open_inquirer_github( + inquirer: String, + clone_url: String, + ref_name: String, +) -> status::Accepted> { let param = OpenGitParam { inquirer, clone_url, - ref_name + ref_name, }; status::Accepted(Some(Json(param))) } @@ -227,9 +227,16 @@ pub fn v1_open_inquirer_github(inquirer: String, clone_url: String, ref_name: St #[get("/open/gitlab?&")] pub fn v1_open_gitlab(clone_url: String, ref_name: String) -> status::Accepted> { let param = OpenGitParam { - inquirer : "foo".to_owned(), + inquirer: "foo".to_owned(), clone_url, - ref_name + ref_name, }; status::Accepted(Some(Json(param))) } + +fn create_ide_id(param: &OpenGitParam) -> String { + let mut s = DefaultHasher::new(); + param.hash(&mut s); + let hash = s.finish(); + format!("{:x}", hash) +} diff --git a/server/podman/Cargo.toml b/server/podman/Cargo.toml index 5f8146b..17b23d6 100644 --- a/server/podman/Cargo.toml +++ b/server/podman/Cargo.toml @@ -10,4 +10,5 @@ edition = "2018" rocket = "0.4.5" serde = "1.0" serde_derive = "1.0" +serde_json = "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 index 75622cd..acaf49d 100644 --- a/server/podman/src/lib.rs +++ b/server/podman/src/lib.rs @@ -1,38 +1,69 @@ #![feature(proc_macro_hygiene, decl_macro)] - extern crate rocket; - extern crate serde; -#[macro_use] extern crate serde_derive; +extern crate rocket; +extern crate serde; +#[macro_use] +extern crate serde_derive; extern crate nixideserver_lib; +extern crate serde_json; -use rocket::http::Status; -use std::hash::Hash; use nixideserver_lib::*; +use rocket::http::Status; +use std::fs; +use std::hash::Hash; +use std::io::Read; +use std::path::PathBuf; - // 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 +// 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{} +pub struct PodmanEngine { + working_folder: PathBuf, +} + +impl PodmanEngine { + pub fn new(working_folder: PathBuf) -> Self { + Self { + working_folder: working_folder, + } + } +} +#[derive(Serialize, Deserialize)] +struct PodmanIdeStatus { + ide_state: IdeState, +} impl NixIdeManageServiceEngine for PodmanEngine { - fn fetch_current_ide_state(&self, _ide_id : &str) -> Result { + 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) + fn start_open(&self, ide_id: &str, _param: &OpenGitParam) -> Result { + let ide_folder = format!("{}/{}", &self.working_folder.display(), ide_id); + let state_file = format!("{}/.ide_state", ide_folder); + fs::create_dir_all(&ide_folder) + .and_then(|_| fs::File::create(state_file)) + .and_then(|mut file| { + let mut contents = String::new(); + match file.read_to_string(&mut contents)? { + 0 => Ok(IdeState::OPENING), + _ => { + let status: PodmanIdeStatus = serde_json::from_str(&contents)?; + Ok(status.ide_state) + } + } + }) + .map_err(|_| Status::new(500, "internal error")) + // 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() } } @@ -47,7 +78,7 @@ pub struct NixIdeServerParam { #[serde(default = "default_project_folder")] project_folder: String, #[serde(default = "default_working_folder")] - working_folder: String + working_folder: String, } fn default_listen_address() -> String { @@ -55,7 +86,7 @@ fn default_listen_address() -> String { } fn default_listen_port() -> u32 { - 3000 + 3000 } fn default_app_folder() -> String {