podman engine setp ide folder

This commit is contained in:
stubbfelnewpc
2020-06-27 20:31:03 +02:00
parent 85bd8eb18c
commit ee1a48a28e
6 changed files with 192 additions and 144 deletions

2
Cargo.lock generated
View File

@@ -684,6 +684,7 @@ name = "nixideserver_cli"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"nixideserver_lib", "nixideserver_lib",
"nixideserver_podman_lib",
"okapi", "okapi",
"rocket", "rocket",
"rocket_okapi", "rocket_okapi",
@@ -711,6 +712,7 @@ dependencies = [
"rocket", "rocket",
"serde", "serde",
"serde_derive", "serde_derive",
"serde_json",
] ]
[[package]] [[package]]

View File

@@ -10,4 +10,5 @@ edition = "2018"
rocket = "0.4.5" rocket = "0.4.5"
rocket_okapi = "0.5.1" rocket_okapi = "0.5.1"
okapi = "0.4.0" okapi = "0.4.0"
nixideserver_lib = { path = "../lib"} nixideserver_lib = { path = "../lib"}
nixideserver_podman_lib = {path = "../podman"}

View File

@@ -1,26 +1,32 @@
#![feature(proc_macro_hygiene, decl_macro)] #![feature(proc_macro_hygiene, decl_macro)]
extern crate rocket; extern crate rocket;
#[macro_use] extern crate rocket_okapi; #[macro_use]
extern crate okapi; extern crate rocket_okapi;
extern crate nixideserver_lib; extern crate nixideserver_lib;
extern crate nixideserver_podman_lib;
extern crate okapi;
use rocket_okapi::{ use nixideserver_podman_lib::PodmanEngine;
swagger_ui::*, use rocket_okapi::swagger_ui::*;
}; use std::env;
use nixideserver_lib::*; use nixideserver_lib::*;
fn main() { fn main() {
let eng = DummyEngine{}; let eng = DummyEngine {};
let _podman_eng = PodmanEngine::new(env::current_dir().unwrap());
let exectuor = NixIdeManageService::new(Box::new(eng)); let exectuor = NixIdeManageService::new(Box::new(eng));
rocket::ignite() rocket::ignite()
.mount("/api/v1/", routes_with_openapi![ .mount(
v1_open_inquirer_git, "/api/v1/",
v1_open_inquirer_gitea, routes_with_openapi![
v1_open_gitlab, v1_open_inquirer_git,
v1_open_inquirer_github, v1_open_inquirer_gitea,
v1_open_inquirer_gitlab, v1_open_gitlab,
v1_ide_state v1_open_inquirer_github,
]) v1_open_inquirer_gitlab,
v1_ide_state
],
)
.manage(exectuor) .manage(exectuor)
.mount( .mount(
"/swagger-ui/", "/swagger-ui/",

View File

@@ -1,93 +1,79 @@
#![feature(proc_macro_hygiene, decl_macro)] #![feature(proc_macro_hygiene, decl_macro)]
#[macro_use] extern crate rocket; #[macro_use]
#[macro_use] extern crate serde_derive; extern crate rocket;
#[macro_use] extern crate rocket_okapi; #[macro_use]
extern crate serde_derive;
#[macro_use]
extern crate rocket_okapi;
extern crate okapi;
extern crate schemars;
extern crate serde; extern crate serde;
extern crate serde_json; 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 okapi::openapi3::Responses;
use rocket_contrib::json::{Json}; use rocket::{
use std::collections::hash_map::DefaultHasher; http::{hyper::header::Location, Status},
use std::hash::{ request::Request,
Hash, response::status,
Hasher 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)] #[derive(Serialize, Deserialize, Hash, JsonSchema, Clone)]
pub enum IdeState pub enum IdeState {
{
UNKOWN, UNKOWN,
OPENING, OPENING,
OPENED, OPENED,
CLOSING, CLOSING,
CLOSED, CLOSED,
DELETING, DELETING,
DELETED DELETED,
}
#[derive(Serialize, Deserialize, Hash, JsonSchema)]
pub struct OpenGitParam
{
inquirer: String,
clone_url: String,
ref_name: String
} }
#[derive(Serialize, Deserialize, Hash, JsonSchema)] #[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, ide_id: String,
state: IdeState, state: IdeState,
href: Option<String> href: Option<String>,
} }
pub trait NixIdeManageServiceEngine { pub trait NixIdeManageServiceEngine {
fn fetch_current_ide_state(&self, ide_id : &str) -> Result<IdeState, Status>; fn fetch_current_ide_state(&self, ide_id: &str) -> Result<IdeState, Status>;
fn start_open(&self, ide_id : &str, param : &OpenGitParam) -> Result<IdeState, Status>; fn start_open(&self, ide_id: &str, param: &OpenGitParam) -> Result<IdeState, Status>;
} }
pub struct NixIdeManageService { pub struct NixIdeManageService {
eng :Box<dyn NixIdeManageServiceEngine> eng: Box<dyn NixIdeManageServiceEngine>,
} }
impl NixIdeManageService { impl NixIdeManageService {
pub fn new(engine : Box<dyn NixIdeManageServiceEngine>) -> Self pub fn new(engine: Box<dyn NixIdeManageServiceEngine>) -> Self {
{ Self { eng: engine }
Self {
eng : engine
}
} }
} }
unsafe impl Send for NixIdeManageService {} unsafe impl Send for NixIdeManageService {}
unsafe impl Sync for NixIdeManageService {} unsafe impl Sync for NixIdeManageService {}
pub struct DummyEngine{} pub struct DummyEngine {}
impl NixIdeManageServiceEngine for DummyEngine { impl NixIdeManageServiceEngine for DummyEngine {
fn fetch_current_ide_state(&self, _ide_id : &str) -> Result<IdeState, Status> { fn fetch_current_ide_state(&self, _ide_id: &str) -> Result<IdeState, Status> {
Ok(IdeState::OPENING) Ok(IdeState::OPENING)
} }
fn start_open(&self, _ide_id : &str, _param : &OpenGitParam) -> Result<IdeState, Status> fn start_open(&self, _ide_id: &str, _param: &OpenGitParam) -> Result<IdeState, Status> {
{
Ok(IdeState::OPENING) Ok(IdeState::OPENING)
} }
} }
@@ -114,12 +100,12 @@ impl<'r, T: OpenApiResponder<'r>> OpenApiResponder<'r> for LocationHeader<T> {
fn responses(gen: &mut OpenApiGenerator) -> rocket_okapi::Result<Responses> { fn responses(gen: &mut OpenApiGenerator) -> rocket_okapi::Result<Responses> {
let mut responses = T::responses(gen)?; let mut responses = T::responses(gen)?;
let mut rep = okapi::openapi3::Response::default(); let mut rep = okapi::openapi3::Response::default();
let header = okapi::openapi3::Header{ let header = okapi::openapi3::Header {
description: Some("Location Header".to_owned()), description: Some("Location Header".to_owned()),
required: true, required: true,
deprecated: false, deprecated: false,
allow_empty_value: false, allow_empty_value: false,
value: okapi::openapi3::ParameterValue::Schema { value: okapi::openapi3::ParameterValue::Schema {
style: None, style: None,
explode: None, explode: None,
allow_reserved: false, allow_reserved: false,
@@ -129,8 +115,13 @@ impl<'r, T: OpenApiResponder<'r>> OpenApiResponder<'r> for LocationHeader<T> {
}, },
extensions: Object::default(), extensions: Object::default(),
}; };
rep.headers.insert("Location".to_owned(), okapi::openapi3::RefOr::Object(header)); rep.headers.insert(
responses.responses.insert(String::new(), okapi::openapi3::RefOr::Object(rep)); "Location".to_owned(),
okapi::openapi3::RefOr::Object(header),
);
responses
.responses
.insert(String::new(), okapi::openapi3::RefOr::Object(rep));
Ok(responses) Ok(responses)
} }
} }
@@ -138,87 +129,96 @@ impl<'r, T: OpenApiResponder<'r>> OpenApiResponder<'r> for LocationHeader<T> {
#[derive(Debug)] #[derive(Debug)]
pub struct Error {} pub struct Error {}
#[openapi] #[openapi]
#[get("/open/<inquirer>/git?<clone_url>&<ref_name>")] #[get("/open/<inquirer>/git?<clone_url>&<ref_name>")]
pub fn v1_open_inquirer_git(inquirer: String, clone_url: String, ref_name: String, srv : State<NixIdeManageService>) -> Result<status::Accepted<Json<IdeStateResponse>>, Error> { pub fn v1_open_inquirer_git(
inquirer: String,
clone_url: String,
ref_name: String,
srv: State<NixIdeManageService>,
) -> Result<status::Accepted<Json<IdeStateResponse>>, Error> {
let param = OpenGitParam { let param = OpenGitParam {
inquirer, inquirer,
clone_url, clone_url,
ref_name ref_name,
}; };
let mut s = DefaultHasher::new(); let ide_id = create_ide_id(&param);
param.hash(&mut s);
let hash = s.finish();
let ide_id = format!("{:x}", hash); srv.eng
srv.eng.start_open(&ide_id, &param).map_err(|_| {Error {}}).and_then(|starting_result| { .start_open(&ide_id, &param)
Ok( .map_err(|_| Error {})
status::Accepted ( .and_then(|starting_result| {
Some( Ok(status::Accepted(Some(Json(IdeStateResponse {
Json( state: starting_result,
IdeStateResponse { href: Some(format!("/api/v1/state/{}", ide_id)),
state : starting_result, ide_id: ide_id,
href: Some(format!("/api/v1/state/{}", ide_id)), }))))
ide_id : ide_id })
}
)
)
)
)
})
} }
#[openapi] #[openapi]
#[get("/state/<ide_id>")] #[get("/state/<ide_id>")]
pub fn v1_ide_state(ide_id: String, srv : State<NixIdeManageService>) -> Result<Json<IdeStateResponse>, status::NotFound<String>> pub fn v1_ide_state(
{ ide_id: String,
srv.eng.fetch_current_ide_state(&ide_id).and_then(|ide_state| { srv: State<NixIdeManageService>,
Ok( ) -> Result<Json<IdeStateResponse>, status::NotFound<String>> {
Json( srv.eng
IdeStateResponse{ .fetch_current_ide_state(&ide_id)
href: Some(match &ide_state { .and_then(|ide_state| {
IdeState::OPENED => format!("/xxx/{}", ide_id), Ok(Json(IdeStateResponse {
_ => format!("/api/v1/state/{}", ide_id) href: Some(match &ide_state {
}), IdeState::OPENED => format!("/xxx/{}", ide_id),
ide_id: ide_id, _ => format!("/api/v1/state/{}", ide_id),
state : ide_state }),
} ide_id: ide_id,
) state: ide_state,
) }))
}).map_err(|_| status::NotFound("Sorry, I couldn't find it!".to_owned())) })
.map_err(|_| status::NotFound("Sorry, I couldn't find it!".to_owned()))
} }
#[openapi] #[openapi]
#[get("/open/<inquirer>/gitea?<clone_url>&<ref_name>")] #[get("/open/<inquirer>/gitea?<clone_url>&<ref_name>")]
pub fn v1_open_inquirer_gitea(inquirer: String, clone_url: String, ref_name: String) -> status::Accepted<Json<OpenGitParam>> { pub fn v1_open_inquirer_gitea(
inquirer: String,
clone_url: String,
ref_name: String,
) -> status::Accepted<Json<OpenGitParam>> {
let param = OpenGitParam { let param = OpenGitParam {
inquirer, inquirer,
clone_url, clone_url,
ref_name ref_name,
}; };
status::Accepted(Some(Json(param))) status::Accepted(Some(Json(param)))
} }
#[openapi] #[openapi]
#[get("/open/<inquirer>/gitlab?<clone_url>&<ref_name>")] #[get("/open/<inquirer>/gitlab?<clone_url>&<ref_name>")]
pub fn v1_open_inquirer_gitlab(inquirer: String, clone_url: String, ref_name: String) -> status::Accepted<Json<OpenGitParam>> { pub fn v1_open_inquirer_gitlab(
inquirer: String,
clone_url: String,
ref_name: String,
) -> status::Accepted<Json<OpenGitParam>> {
let param = OpenGitParam { let param = OpenGitParam {
inquirer, inquirer,
clone_url, clone_url,
ref_name ref_name,
}; };
status::Accepted(Some(Json(param))) status::Accepted(Some(Json(param)))
} }
#[openapi] #[openapi]
#[get("/open/<inquirer>/github?<clone_url>&<ref_name>")] #[get("/open/<inquirer>/github?<clone_url>&<ref_name>")]
pub fn v1_open_inquirer_github(inquirer: String, clone_url: String, ref_name: String) -> status::Accepted<Json<OpenGitParam>> { pub fn v1_open_inquirer_github(
inquirer: String,
clone_url: String,
ref_name: String,
) -> status::Accepted<Json<OpenGitParam>> {
let param = OpenGitParam { let param = OpenGitParam {
inquirer, inquirer,
clone_url, clone_url,
ref_name ref_name,
}; };
status::Accepted(Some(Json(param))) 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?<clone_url>&<ref_name>")] #[get("/open/gitlab?<clone_url>&<ref_name>")]
pub fn v1_open_gitlab(clone_url: String, ref_name: String) -> status::Accepted<Json<OpenGitParam>> { pub fn v1_open_gitlab(clone_url: String, ref_name: String) -> status::Accepted<Json<OpenGitParam>> {
let param = OpenGitParam { let param = OpenGitParam {
inquirer : "foo".to_owned(), inquirer: "foo".to_owned(),
clone_url, clone_url,
ref_name ref_name,
}; };
status::Accepted(Some(Json(param))) 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)
}

View File

@@ -10,4 +10,5 @@ edition = "2018"
rocket = "0.4.5" rocket = "0.4.5"
serde = "1.0" serde = "1.0"
serde_derive = "1.0" serde_derive = "1.0"
serde_json = "1.0"
nixideserver_lib = { path = "../lib"} nixideserver_lib = { path = "../lib"}

View File

@@ -1,38 +1,69 @@
#![feature(proc_macro_hygiene, decl_macro)] #![feature(proc_macro_hygiene, decl_macro)]
extern crate rocket; extern crate rocket;
extern crate serde; extern crate serde;
#[macro_use] extern crate serde_derive; #[macro_use]
extern crate serde_derive;
extern crate nixideserver_lib; extern crate nixideserver_lib;
extern crate serde_json;
use rocket::http::Status;
use std::hash::Hash;
use nixideserver_lib::*; 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 { impl NixIdeManageServiceEngine for PodmanEngine {
fn fetch_current_ide_state(&self, _ide_id : &str) -> Result<IdeState, Status> { fn fetch_current_ide_state(&self, _ide_id: &str) -> Result<IdeState, Status> {
Ok(IdeState::OPENING) Ok(IdeState::OPENING)
} }
fn start_open(&self, _ide_id : &str, _param : &OpenGitParam) -> Result<IdeState, Status> { fn start_open(&self, ide_id: &str, _param: &OpenGitParam) -> Result<IdeState, Status> {
let ide_folder = format!("{}/{}", &self.working_folder.display(), ide_id);
// println!("foo {:x}", hash); let state_file = format!("{}/.ide_state", ide_folder);
// let out = Command::new("podman") fs::create_dir_all(&ide_folder)
// .arg("create") .and_then(|_| fs::File::create(state_file))
// .arg("--name") .and_then(|mut file| {
// .arg(format!("{:x}", hash)) let mut contents = String::new();
// .arg("-p") match file.read_to_string(&mut contents)? {
// .arg("3000:3000") 0 => Ok(IdeState::OPENING),
// .arg("docker.io/nixos/nix") _ => {
// // .arg(format!("git clone {}", param.clone_url)) let status: PodmanIdeStatus = serde_json::from_str(&contents)?;
// .output() Ok(status.ide_state)
// .expect("create container"); }
// String::from_utf8(out.stderr).unwrap() }
})
Ok(IdeState::OPENING) .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")] #[serde(default = "default_project_folder")]
project_folder: String, project_folder: String,
#[serde(default = "default_working_folder")] #[serde(default = "default_working_folder")]
working_folder: String working_folder: String,
} }
fn default_listen_address() -> String { fn default_listen_address() -> String {
@@ -55,7 +86,7 @@ fn default_listen_address() -> String {
} }
fn default_listen_port() -> u32 { fn default_listen_port() -> u32 {
3000 3000
} }
fn default_app_folder() -> String { fn default_app_folder() -> String {