Skip to content
This repository has been archived by the owner on Jul 2, 2024. It is now read-only.

Commit

Permalink
Merge pull request #26 from tsirysndr/feat/build-command
Browse files Browse the repository at this point in the history
feat: implement `build` subcommand (for building services)
  • Loading branch information
tsirysndr authored Mar 29, 2023
2 parents 7e6ad7e + 7567836 commit 363904b
Show file tree
Hide file tree
Showing 19 changed files with 501 additions and 90 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ OPTIONS:
-V, --version Print version information
SUBCOMMANDS:
build Build all services or a specific one
config Get the config of a service
down Stop all services
help Print this message or the help of the given subcommand(s)
Expand Down
3 changes: 3 additions & 0 deletions examples/nginx-nodejs-redis/Superfile.hcl
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ services = [
flox = {
"environment" = ".#nginx-nodejs-redis"
}
build = {
"command" = "npm install"
}
},
{
"name" = "redis"
Expand Down
10 changes: 10 additions & 0 deletions proto/superviseur/v1alpha1/control.proto
Original file line number Diff line number Diff line change
Expand Up @@ -66,12 +66,22 @@ message ListResponse {
repeated objects.v1alpha1.Service services = 1;
}

message BuildRequest {
string name = 1;
string config_file_path = 2;
}

message BuildResponse {
bool success = 1;
}

service ControlService {
rpc LoadConfig (LoadConfigRequest) returns (LoadConfigResponse) {}
rpc Start (StartRequest) returns (StartResponse) {}
rpc Stop (StopRequest) returns (StopResponse) {}
rpc Restart (RestartRequest) returns (RestartResponse) {}
rpc Status (StatusRequest) returns (StatusResponse) {}
rpc List (ListRequest) returns (ListResponse) {}
rpc Build (BuildRequest) returns (BuildResponse) {}
rpc ListRunningProcesses (ListRunningProcessesRequest) returns (ListRunningProcessesResponse) {}
}
74 changes: 74 additions & 0 deletions src/api/superviseur.v1alpha1.rs
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,20 @@ pub struct ListResponse {
#[prost(message, repeated, tag = "1")]
pub services: ::prost::alloc::vec::Vec<super::super::objects::v1alpha1::Service>,
}
#[allow(clippy::derive_partial_eq_without_eq)]
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct BuildRequest {
#[prost(string, tag = "1")]
pub name: ::prost::alloc::string::String,
#[prost(string, tag = "2")]
pub config_file_path: ::prost::alloc::string::String,
}
#[allow(clippy::derive_partial_eq_without_eq)]
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct BuildResponse {
#[prost(bool, tag = "1")]
pub success: bool,
}
/// Generated client implementations.
pub mod control_service_client {
#![allow(unused_variables, dead_code, missing_docs, clippy::let_unit_value)]
Expand Down Expand Up @@ -275,6 +289,25 @@ pub mod control_service_client {
);
self.inner.unary(request.into_request(), path, codec).await
}
pub async fn build(
&mut self,
request: impl tonic::IntoRequest<super::BuildRequest>,
) -> Result<tonic::Response<super::BuildResponse>, tonic::Status> {
self.inner
.ready()
.await
.map_err(|e| {
tonic::Status::new(
tonic::Code::Unknown,
format!("Service was not ready: {}", e.into()),
)
})?;
let codec = tonic::codec::ProstCodec::default();
let path = http::uri::PathAndQuery::from_static(
"/superviseur.v1alpha1.ControlService/Build",
);
self.inner.unary(request.into_request(), path, codec).await
}
pub async fn list_running_processes(
&mut self,
request: impl tonic::IntoRequest<super::ListRunningProcessesRequest>,
Expand Down Expand Up @@ -330,6 +363,10 @@ pub mod control_service_server {
&self,
request: tonic::Request<super::ListRequest>,
) -> Result<tonic::Response<super::ListResponse>, tonic::Status>;
async fn build(
&self,
request: tonic::Request<super::BuildRequest>,
) -> Result<tonic::Response<super::BuildResponse>, tonic::Status>;
async fn list_running_processes(
&self,
request: tonic::Request<super::ListRunningProcessesRequest>,
Expand Down Expand Up @@ -619,6 +656,43 @@ pub mod control_service_server {
};
Box::pin(fut)
}
"/superviseur.v1alpha1.ControlService/Build" => {
#[allow(non_camel_case_types)]
struct BuildSvc<T: ControlService>(pub Arc<T>);
impl<
T: ControlService,
> tonic::server::UnaryService<super::BuildRequest> for BuildSvc<T> {
type Response = super::BuildResponse;
type Future = BoxFuture<
tonic::Response<Self::Response>,
tonic::Status,
>;
fn call(
&mut self,
request: tonic::Request<super::BuildRequest>,
) -> Self::Future {
let inner = self.0.clone();
let fut = async move { (*inner).build(request).await };
Box::pin(fut)
}
}
let accept_compression_encodings = self.accept_compression_encodings;
let send_compression_encodings = self.send_compression_encodings;
let inner = self.inner.clone();
let fut = async move {
let inner = inner.0;
let method = BuildSvc(inner);
let codec = tonic::codec::ProstCodec::default();
let mut grpc = tonic::server::Grpc::new(codec)
.apply_compression_config(
accept_compression_encodings,
send_compression_encodings,
);
let res = grpc.unary(method, req).await;
Ok(res)
};
Box::pin(fut)
}
"/superviseur.v1alpha1.ControlService/ListRunningProcesses" => {
#[allow(non_camel_case_types)]
struct ListRunningProcessesSvc<T: ControlService>(pub Arc<T>);
Expand Down
39 changes: 39 additions & 0 deletions src/cmd/build.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
use anyhow::Error;
use tokio::net::UnixStream;
use tonic::transport::{ Endpoint, Uri};
use tower::service_fn;

use crate::{config::verify_if_config_file_is_present, types::{SUPERFILE, UNIX_SOCKET_PATH}, api::superviseur::v1alpha1::{BuildRequest, control_service_client::ControlServiceClient, LoadConfigRequest}};

pub async fn execute_build(name: Option<&str>) -> Result<(), Error> {
verify_if_config_file_is_present()?;
let current_dir = std::env::current_dir()?;
let config = std::fs::read_to_string(current_dir.join(SUPERFILE))?;

let channel = Endpoint::try_from("http://[::]:50051")?
.connect_with_connector(service_fn(move |_: Uri| UnixStream::connect(UNIX_SOCKET_PATH)))
.await
.map_err(|_|
Error::msg(format!("Cannot connect to the Superviseur daemon at unix:{}. Is the superviseur daemon running?", UNIX_SOCKET_PATH)))?;

// let mut client = ControlServiceClient::connect("http://127.0.0.1:5476").await?;
let mut client = ControlServiceClient::new(channel);

let request = tonic::Request::new(LoadConfigRequest {
config,
file_path: current_dir.to_str().unwrap().to_string(),
});

client.load_config(request).await?;

let name = name.unwrap_or_default().to_string();

let request = tonic::Request::new(BuildRequest {
name,
config_file_path: current_dir.to_str().unwrap().to_string(),
});

client.build(request).await?;

Ok(())
}
1 change: 1 addition & 0 deletions src/cmd/mod.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
pub mod build;
pub mod config;
pub mod init;
pub mod list;
Expand Down
1 change: 1 addition & 0 deletions src/cmd/new.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ pub fn execute_new(cfg_format: ConfigFormat) {
stderr: "/tmp/demo-stderr.log".to_string(),
wait_for: None,
flox: None,
build: None,
}],
};
let serialized = match cfg_format {
Expand Down
1 change: 0 additions & 1 deletion src/cmd/ui.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,5 +52,4 @@ pub async fn execute_ui() -> Result<(), Error> {
tokio::time::sleep(tokio::time::Duration::from_secs(1)).await;
}

Ok(())
}
38 changes: 38 additions & 0 deletions src/graphql/schema/objects/subscriptions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -148,3 +148,41 @@ impl AllServicesRestarted {
&self.payload
}
}

#[derive(Default, Clone)]
pub struct ServiceBuilding {
pub payload: Service,
pub process: Process,
}

#[Object]
impl ServiceBuilding {
async fn payload(&self) -> &Service {
&self.payload
}
}

#[derive(Default, Clone)]
pub struct ServiceBuilt {
pub payload: Service,
pub process: Process,
}

#[Object]
impl ServiceBuilt {
async fn payload(&self) -> &Service {
&self.payload
}
}

#[derive(Default, Clone)]
pub struct AllServicesBuilt {
pub payload: Vec<Service>,
}

#[Object]
impl AllServicesBuilt {
async fn payload(&self) -> &Vec<Service> {
&self.payload
}
}
14 changes: 11 additions & 3 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,10 @@ use anyhow::Error;
use clap::{arg, Command};
use superviseur::{
cmd::{
config::execute_config, init::execute_init, list::execute_list, log::execute_log,
new::execute_new, ps::execute_ps, restart::execute_restart, start::execute_start,
status::execute_status, stop::execute_stop, tail::execute_tail, ui::execute_ui,
build::execute_build, config::execute_config, init::execute_init, list::execute_list,
log::execute_log, new::execute_new, ps::execute_ps, restart::execute_restart,
start::execute_start, status::execute_status, stop::execute_stop, tail::execute_tail,
ui::execute_ui,
},
server,
types::configuration::ConfigFormat,
Expand Down Expand Up @@ -89,6 +90,9 @@ A simple process supervisor"#,
.subcommand(Command::new("up").about("Start all services"))
.subcommand(Command::new("down").about("Stop all services"))
.subcommand(Command::new("ui").about("Start the superviseur ui"))
.subcommand(Command::new("build")
.arg(arg!([name] "The name of the service to build, if not specified, all services will be built"))
.about("Build all services or a specific one"))
}

#[tokio::main]
Expand Down Expand Up @@ -147,6 +151,10 @@ async fn main() -> Result<(), Error> {
Some(("up", _)) => execute_start(None).await?,
Some(("down", _)) => execute_stop(None).await?,
Some(("ui", _)) => execute_ui().await?,
Some(("build", args)) => {
let name = args.value_of("name");
execute_build(name).await?;
}
_ => cli().print_help()?,
}
Ok(())
Expand Down
51 changes: 46 additions & 5 deletions src/server/control.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
use std::{
collections::HashMap,
path::Path,
sync::{Arc, Mutex},
thread,
time::Duration,
Expand All @@ -15,10 +14,10 @@ use crate::{
api::{
objects::v1alpha1::Service,
superviseur::v1alpha1::{
control_service_server::ControlService, ListRequest, ListResponse,
ListRunningProcessesRequest, ListRunningProcessesResponse, LoadConfigRequest,
LoadConfigResponse, RestartRequest, RestartResponse, StartRequest, StartResponse,
StatusRequest, StatusResponse, StopRequest, StopResponse,
control_service_server::ControlService, BuildRequest, BuildResponse, ListRequest,
ListResponse, ListRunningProcessesRequest, ListRunningProcessesResponse,
LoadConfigRequest, LoadConfigResponse, RestartRequest, RestartResponse, StartRequest,
StartResponse, StatusRequest, StatusResponse, StopRequest, StopResponse,
},
},
superviseur::core::{ProcessEvent, Superviseur, SuperviseurCommand},
Expand Down Expand Up @@ -401,4 +400,46 @@ impl ControlService for Control {
};
Ok(Response::new(list_response))
}

async fn build(
&self,
request: Request<BuildRequest>,
) -> Result<Response<BuildResponse>, tonic::Status> {
let request = request.into_inner();
let path = request.config_file_path;
let name = request.name;
let config_map = self.config_map.lock().unwrap();

if !config_map.contains_key(&path) {
return Err(tonic::Status::not_found("Config file not found"));
}

let config = config_map.get(&path).unwrap();

if name.len() > 0 {
let service = config
.services
.iter()
.find(|s| s.name == name)
.ok_or_else(|| tonic::Status::not_found("Service not found"))?;

service
.build
.as_ref()
.ok_or_else(|| tonic::Status::invalid_argument("Service has no build command"))?;

self.cmd_tx
.send(SuperviseurCommand::Build(
service.clone(),
config.project.clone(),
))
.map_err(|e| tonic::Status::internal(e.to_string()))?;
return Ok(Response::new(BuildResponse { success: true }));
}

self.cmd_tx
.send(SuperviseurCommand::BuildAll(config.project.clone()))
.map_err(|e| tonic::Status::internal(e.to_string()))?;
Ok(Response::new(BuildResponse { success: true }))
}
}
1 change: 0 additions & 1 deletion src/server/core.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
use std::{
collections::HashMap,
error::Error,
sync::{Arc, Mutex},
thread,
};
Expand Down
Loading

0 comments on commit 363904b

Please sign in to comment.