split up in severals libs

This commit is contained in:
stubbfelnewpc
2020-06-27 18:59:47 +02:00
parent 74473ba10f
commit 85bd8eb18c
8 changed files with 370 additions and 288 deletions

20
Cargo.lock generated
View File

@@ -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"

View File

@@ -1,2 +1,2 @@
[workspace]
members = ["control/cli", "server/cli"]
members = ["control/cli", "server/cli", "server/lib", "server/podman"]

View File

@@ -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"
okapi = "0.4.0"
nixideserver_lib = { path = "../lib"}

View File

@@ -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<IdeState, Status>;
fn start_open(&self, ide_id : &str, param : &OpenGitParam) -> Result<IdeState, Status>;
}
pub struct NixIdeManageService {
eng :Box<dyn NixIdeManageServiceEngine>
}
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<IdeState, Status> {
Ok(IdeState::OPENING)
}
fn start_open(&self, _ide_id : &str, _param : &OpenGitParam) -> Result<IdeState, Status>
{
Ok(IdeState::OPENING)
}
}
struct PodmanEngine{}
impl NixIdeManageServiceEngine for PodmanEngine {
fn fetch_current_ide_state(&self, _ide_id : &str) -> Result<IdeState, Status> {
Ok(IdeState::OPENING)
}
fn start_open(&self, _ide_id : &str, _param : &OpenGitParam) -> Result<IdeState, Status>{
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<R>(pub Option<R>, 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<R> {
fn respond_to(self, req: &Request) -> Result<Response<'r>, 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<K, V> = schemars::Map<K, V>;
type Object = Map<String, serde_json::Value>;
impl<'r, T: OpenApiResponder<'r>> OpenApiResponder<'r> for LocationHeader<T> {
fn responses(gen: &mut OpenApiGenerator) -> rocket_okapi::Result<Responses> {
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/<inquirer>/git?<clone_url>&<ref_name>")]
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 {
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, &param).map_err(|_| {Error {}}).and_then(|starting_result| {
Ok(
status::Accepted (
Some(
Json(
IdeStateResponse {
ide_id : ide_id,
state : starting_result
}
)
)
)
)
})
}
#[openapi]
#[get("/state/<ide_ide>")]
fn v1_ide_state(ide_ide: String, srv : State<NixIdeManageService>) -> Json<IdeStateResponse>
{
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/<inquirer>/gitea?<clone_url>&<ref_name>")]
fn v1_open_inquirer_gitea(inquirer: String, clone_url: String, ref_name: String) -> status::Accepted<Json<OpenGitParam>> {
let param = OpenGitParam {
inquirer,
clone_url,
ref_name
};
status::Accepted(Some(Json(param)))
}
#[openapi]
#[get("/open/<inquirer>/gitlab?<clone_url>&<ref_name>")]
fn v1_open_inquirer_gitlab(inquirer: String, clone_url: String, ref_name: String) -> status::Accepted<Json<OpenGitParam>> {
let param = OpenGitParam {
inquirer,
clone_url,
ref_name
};
status::Accepted(Some(Json(param)))
}
#[openapi]
#[get("/open/<inquirer>/github?<clone_url>&<ref_name>")]
fn v1_open_inquirer_github(inquirer: String, clone_url: String, ref_name: String) -> status::Accepted<Json<OpenGitParam>> {
let param = OpenGitParam {
inquirer,
clone_url,
ref_name
};
status::Accepted(Some(Json(param)))
}
#[openapi]
#[get("/open/gitlab?<clone_url>&<ref_name>")]
fn v1_open_gitlab(clone_url: String, ref_name: String) -> status::Accepted<Json<OpenGitParam>> {
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(

17
server/lib/Cargo.toml Normal file
View File

@@ -0,0 +1,17 @@
[package]
name = "nixideserver_lib"
version = "0.1.0"
authors = ["stubbfelnewpc <stubbfelnewpc@stubbe.rocks>"]
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"

235
server/lib/src/lib.rs Normal file
View File

@@ -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<String>
}
pub trait NixIdeManageServiceEngine {
fn fetch_current_ide_state(&self, ide_id : &str) -> Result<IdeState, Status>;
fn start_open(&self, ide_id : &str, param : &OpenGitParam) -> Result<IdeState, Status>;
}
pub struct NixIdeManageService {
eng :Box<dyn NixIdeManageServiceEngine>
}
impl NixIdeManageService {
pub fn new(engine : Box<dyn NixIdeManageServiceEngine>) -> 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<IdeState, Status> {
Ok(IdeState::OPENING)
}
fn start_open(&self, _ide_id : &str, _param : &OpenGitParam) -> Result<IdeState, Status>
{
Ok(IdeState::OPENING)
}
}
pub struct LocationHeader<R>(pub Option<R>, 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<R> {
fn respond_to(self, req: &Request) -> Result<Response<'r>, 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<K, V> = schemars::Map<K, V>;
type Object = Map<String, serde_json::Value>;
impl<'r, T: OpenApiResponder<'r>> OpenApiResponder<'r> for LocationHeader<T> {
fn responses(gen: &mut OpenApiGenerator) -> rocket_okapi::Result<Responses> {
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/<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> {
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, &param).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/<ide_id>")]
pub fn v1_ide_state(ide_id: String, srv : State<NixIdeManageService>) -> Result<Json<IdeStateResponse>, status::NotFound<String>>
{
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/<inquirer>/gitea?<clone_url>&<ref_name>")]
pub fn v1_open_inquirer_gitea(inquirer: String, clone_url: String, ref_name: String) -> status::Accepted<Json<OpenGitParam>> {
let param = OpenGitParam {
inquirer,
clone_url,
ref_name
};
status::Accepted(Some(Json(param)))
}
#[openapi]
#[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>> {
let param = OpenGitParam {
inquirer,
clone_url,
ref_name
};
status::Accepted(Some(Json(param)))
}
#[openapi]
#[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>> {
let param = OpenGitParam {
inquirer,
clone_url,
ref_name
};
status::Accepted(Some(Json(param)))
}
#[openapi]
#[get("/open/gitlab?<clone_url>&<ref_name>")]
pub fn v1_open_gitlab(clone_url: String, ref_name: String) -> status::Accepted<Json<OpenGitParam>> {
let param = OpenGitParam {
inquirer : "foo".to_owned(),
clone_url,
ref_name
};
status::Accepted(Some(Json(param)))
}

13
server/podman/Cargo.toml Normal file
View File

@@ -0,0 +1,13 @@
[package]
name = "nixideserver_podman_lib"
version = "0.1.0"
authors = ["stubbfelnewpc <stubbfelnewpc@stubbe.rocks>"]
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"}

71
server/podman/src/lib.rs Normal file
View File

@@ -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<IdeState, Status> {
Ok(IdeState::OPENING)
}
fn start_open(&self, _ide_id : &str, _param : &OpenGitParam) -> Result<IdeState, Status> {
// 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()
}