feat: update project
This commit is contained in:
@@ -3,42 +3,41 @@
|
||||
#[allow(clippy::derive_partial_eq_without_eq)]
|
||||
#[derive(Clone, PartialEq, ::prost::Message)]
|
||||
pub struct PublishRequest {
|
||||
#[prost(message, optional, tag="1")]
|
||||
#[prost(message, optional, tag = "1")]
|
||||
pub project: ::core::option::Option<Project>,
|
||||
}
|
||||
#[allow(clippy::derive_partial_eq_without_eq)]
|
||||
#[derive(Clone, Copy, PartialEq, ::prost::Message)]
|
||||
pub struct PublishResponse {
|
||||
}
|
||||
pub struct PublishResponse {}
|
||||
#[allow(clippy::derive_partial_eq_without_eq)]
|
||||
#[derive(Clone, PartialEq, ::prost::Message)]
|
||||
pub struct GetTopicRequest {
|
||||
#[prost(string, tag="1")]
|
||||
#[prost(string, tag = "1")]
|
||||
pub topic: ::prost::alloc::string::String,
|
||||
}
|
||||
#[allow(clippy::derive_partial_eq_without_eq)]
|
||||
#[derive(Clone, PartialEq, ::prost::Message)]
|
||||
pub struct GetTopicResponse {
|
||||
#[prost(message, optional, tag="1")]
|
||||
#[prost(message, optional, tag = "1")]
|
||||
pub projects: ::core::option::Option<Projects>,
|
||||
}
|
||||
#[allow(clippy::derive_partial_eq_without_eq)]
|
||||
#[derive(Clone, PartialEq, ::prost::Message)]
|
||||
pub struct Projects {
|
||||
#[prost(message, repeated, tag="1")]
|
||||
#[prost(message, repeated, tag = "1")]
|
||||
pub projects: ::prost::alloc::vec::Vec<Project>,
|
||||
}
|
||||
#[allow(clippy::derive_partial_eq_without_eq)]
|
||||
#[derive(Clone, PartialEq, ::prost::Message)]
|
||||
pub struct Project {
|
||||
#[prost(string, tag="1")]
|
||||
#[prost(string, tag = "1")]
|
||||
pub name: ::prost::alloc::string::String,
|
||||
#[prost(string, tag="2")]
|
||||
#[prost(string, tag = "2")]
|
||||
pub image: ::prost::alloc::string::String,
|
||||
#[prost(string, tag="3")]
|
||||
#[prost(string, tag = "3")]
|
||||
pub version: ::prost::alloc::string::String,
|
||||
#[prost(uint32, optional, tag="4")]
|
||||
#[prost(uint32, optional, tag = "4")]
|
||||
pub port: ::core::option::Option<u32>,
|
||||
}
|
||||
include!("norun.v1.tonic.rs");
|
||||
// @@protoc_insertion_point(module)
|
||||
// @@protoc_insertion_point(module)
|
||||
|
@@ -23,6 +23,9 @@ async-trait = "0.1.88"
|
||||
notmad = "0.7.2"
|
||||
bollard = "0.19.1"
|
||||
futures-util = "0.3.31"
|
||||
dirs = "6.0.0"
|
||||
uuid = { version = "1.17.0", features = ["serde", "v4"] }
|
||||
ron = "0.10.1"
|
||||
|
||||
[dev-dependencies]
|
||||
pretty_assertions = "1.4.1"
|
||||
|
@@ -7,6 +7,8 @@ mod state;
|
||||
|
||||
mod server;
|
||||
|
||||
mod services;
|
||||
|
||||
mod grpc_client;
|
||||
mod grpc_server;
|
||||
|
||||
|
@@ -1,5 +1,7 @@
|
||||
pub mod project_tag;
|
||||
pub use project_tag::*;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use uuid::Uuid;
|
||||
|
||||
pub mod port {
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
@@ -8,3 +10,15 @@ pub mod port {
|
||||
pub container_port: usize,
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Deserialize, Serialize)]
|
||||
pub struct Project {
|
||||
pub id: Uuid,
|
||||
pub spec: ProjectSpec,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Deserialize, Serialize)]
|
||||
pub enum ProjectSpec {
|
||||
Compose {},
|
||||
Container {},
|
||||
}
|
||||
|
1
crates/norun/src/services.rs
Normal file
1
crates/norun/src/services.rs
Normal file
@@ -0,0 +1 @@
|
||||
pub mod project_registry;
|
104
crates/norun/src/services/project_registry.rs
Normal file
104
crates/norun/src/services/project_registry.rs
Normal file
@@ -0,0 +1,104 @@
|
||||
use std::path::PathBuf;
|
||||
|
||||
use anyhow::Context;
|
||||
use tokio::io::AsyncWriteExt;
|
||||
|
||||
use crate::{models::Project, state::ClientState};
|
||||
|
||||
pub struct ProjectRegistry {
|
||||
state_dir: PathBuf,
|
||||
}
|
||||
|
||||
impl ProjectRegistry {
|
||||
pub async fn get_project(&self, project: &Project) -> anyhow::Result<Option<Project>> {
|
||||
let project_dir = self.project_file(project)?;
|
||||
|
||||
if !project_dir.exists() {
|
||||
return Ok(None);
|
||||
}
|
||||
|
||||
let project_content = tokio::fs::read_to_string(&project_dir)
|
||||
.await
|
||||
.context("failed to read ron file")?;
|
||||
|
||||
let project: Project = ron::from_str(&project_content)
|
||||
.context(format!("failed to read: '{}'", project_dir.display()))?;
|
||||
|
||||
Ok(Some(project))
|
||||
}
|
||||
|
||||
pub async fn create_project(&self, project: &Project) -> anyhow::Result<()> {
|
||||
match self.get_project(project).await {
|
||||
Ok(_) => anyhow::bail!("project already exists"),
|
||||
Err(_) => {
|
||||
// continue
|
||||
}
|
||||
}
|
||||
|
||||
let project_file_path = self.project_file(project)?;
|
||||
if let Some(project_file) = project_file_path.parent() {
|
||||
tokio::fs::create_dir_all(project_file)
|
||||
.await
|
||||
.context("create ron project dir")?;
|
||||
}
|
||||
|
||||
let mut project_file = tokio::fs::File::create_new(&project_file_path)
|
||||
.await
|
||||
.context("create project file")?;
|
||||
|
||||
let project_content = ron::to_string(project)?;
|
||||
|
||||
project_file
|
||||
.write_all(&project_content.as_bytes())
|
||||
.await
|
||||
.context("write project file")?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn update_project(&self, project: &Project) -> anyhow::Result<()> {
|
||||
let project_file_path = self.project_file(project)?;
|
||||
if let Some(project_file) = project_file_path.parent() {
|
||||
tokio::fs::create_dir_all(project_file)
|
||||
.await
|
||||
.context("update ron project dir")?;
|
||||
}
|
||||
|
||||
let mut project_file = tokio::fs::File::create_new(&project_file_path)
|
||||
.await
|
||||
.context("update project file")?;
|
||||
|
||||
let project_content = ron::to_string(project)?;
|
||||
|
||||
project_file
|
||||
.write_all(project_content.as_bytes())
|
||||
.await
|
||||
.context("update project file")?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn project_file(&self, project: &Project) -> anyhow::Result<PathBuf> {
|
||||
let project_dir = self
|
||||
.state_dir
|
||||
.join(project.id.to_string())
|
||||
.join("project.ron");
|
||||
|
||||
Ok(project_dir)
|
||||
}
|
||||
}
|
||||
|
||||
pub trait ProjectRegistryState {
|
||||
fn project_registry(&self) -> ProjectRegistry;
|
||||
}
|
||||
|
||||
impl ProjectRegistryState for ClientState {
|
||||
fn project_registry(&self) -> ProjectRegistry {
|
||||
ProjectRegistry {
|
||||
state_dir: dirs::state_dir()
|
||||
.expect("to be able to find state")
|
||||
.join("norun")
|
||||
.join("projects"),
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user