mirror of
https://github.com/faas-rs/faasd-in-rust.git
synced 2025-06-08 15:56:48 +00:00
feat:gateway-mvp implmentation,enable to deploy function,proxy request to the container and delete function's container and task
This commit is contained in:
parent
7258f4f6ed
commit
92b281dc48
@ -8,8 +8,9 @@ pub mod types;
|
|||||||
|
|
||||||
use handlers::*;
|
use handlers::*;
|
||||||
use provider::{
|
use provider::{
|
||||||
handlers::{delete::delete_handler, deploy::deploy_handler},
|
handlers::{delete::delete_handler, deploy::deploy_handler, invoke_resolver::InvokeResolver},
|
||||||
proxy::proxy_handler::proxy_handler,
|
proxy::proxy_handler::proxy_handler,
|
||||||
|
types::config::FaaSConfig,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[actix_web::main]
|
#[actix_web::main]
|
||||||
@ -21,11 +22,16 @@ async fn main() -> std::io::Result<()> {
|
|||||||
.unwrap(),
|
.unwrap(),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
let resolver = Some(InvokeResolver::new(service.clone()).await);
|
||||||
|
let faas_config = FaaSConfig::new();
|
||||||
|
|
||||||
println!("I'm running!");
|
println!("I'm running!");
|
||||||
|
|
||||||
let server = HttpServer::new(move || {
|
let server = HttpServer::new(move || {
|
||||||
App::new()
|
App::new()
|
||||||
.app_data(web::Data::new(service.clone()))
|
.app_data(web::Data::new(service.clone()))
|
||||||
|
.app_data(web::Data::new(resolver.clone()))
|
||||||
|
.app_data(web::Data::new(faas_config.clone()))
|
||||||
.route("/create-container", web::post().to(create_container))
|
.route("/create-container", web::post().to(create_container))
|
||||||
.route("/remove-container", web::post().to(remove_container))
|
.route("/remove-container", web::post().to(remove_container))
|
||||||
.route("/containers", web::get().to(get_container_list))
|
.route("/containers", web::get().to(get_container_list))
|
||||||
|
@ -5,7 +5,7 @@ use crate::{
|
|||||||
utils::{CustomError, map_service_error},
|
utils::{CustomError, map_service_error},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
use actix_web::{HttpResponse, Responder, error, web};
|
use actix_web::{HttpResponse, Responder, ResponseError, error, web};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use service::Service;
|
use service::Service;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
@ -24,10 +24,7 @@ pub async fn delete_handler(
|
|||||||
Ok(()) => {
|
Ok(()) => {
|
||||||
HttpResponse::Ok().body(format!("function {} deleted successfully", function_name))
|
HttpResponse::Ok().body(format!("function {} deleted successfully", function_name))
|
||||||
}
|
}
|
||||||
Err(e) => HttpResponse::InternalServerError().body(format!(
|
Err(e) => e.error_response(),
|
||||||
"failed to delete function {} in namespace {} because {}",
|
|
||||||
function_name, namespace, e
|
|
||||||
)),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,7 +1,8 @@
|
|||||||
use crate::handlers::function_list::Function;
|
use crate::handlers::function_list::Function;
|
||||||
// use service::spec::{ Mount, Spec};
|
// use service::spec::{ Mount, Spec};
|
||||||
use actix_web::cookie::time::Duration;
|
use actix_web::cookie::time::Duration;
|
||||||
use std::{collections::HashMap, time::UNIX_EPOCH};
|
use service::Service;
|
||||||
|
use std::{collections::HashMap, sync::Arc, time::UNIX_EPOCH};
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
|
|
||||||
const ANNOTATION_LABEL_PREFIX: &str = "com.openfaas.annotations.";
|
const ANNOTATION_LABEL_PREFIX: &str = "com.openfaas.annotations.";
|
||||||
@ -21,14 +22,14 @@ impl From<Box<dyn std::error::Error>> for FunctionError {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub async fn get_function(
|
pub async fn get_function(
|
||||||
client: &service::Service,
|
service: &Arc<Service>,
|
||||||
function_name: &str,
|
function_name: &str,
|
||||||
namespace: &str,
|
namespace: &str,
|
||||||
) -> Result<Function, FunctionError> {
|
) -> Result<Function, FunctionError> {
|
||||||
let cid = function_name;
|
let cid = function_name;
|
||||||
let ip = client.get_ip(cid).await.unwrap();
|
let ip = client.get_ip(cid).await.unwrap();
|
||||||
|
|
||||||
let container = client
|
let container = service
|
||||||
.load_container(cid, namespace)
|
.load_container(cid, namespace)
|
||||||
.await
|
.await
|
||||||
.map_err(|e| FunctionError::FunctionNotFound(e.to_string()))?;
|
.map_err(|e| FunctionError::FunctionNotFound(e.to_string()))?;
|
||||||
@ -50,7 +51,7 @@ pub async fn get_function(
|
|||||||
let timestamp = container.created_at.unwrap_or_default();
|
let timestamp = container.created_at.unwrap_or_default();
|
||||||
let created_at = UNIX_EPOCH + Duration::new(timestamp.seconds, timestamp.nanos);
|
let created_at = UNIX_EPOCH + Duration::new(timestamp.seconds, timestamp.nanos);
|
||||||
|
|
||||||
let task = client
|
let task = service
|
||||||
.get_task(cid, namespace)
|
.get_task(cid, namespace)
|
||||||
.await
|
.await
|
||||||
.map_err(|e| FunctionError::FunctionNotFound(e.to_string()));
|
.map_err(|e| FunctionError::FunctionNotFound(e.to_string()));
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
use std::{collections::HashMap, time::SystemTime};
|
use std::{collections::HashMap, time::SystemTime};
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
pub struct Function {
|
pub struct Function {
|
||||||
pub name: String,
|
pub name: String,
|
||||||
pub namespace: String,
|
pub namespace: String,
|
||||||
|
@ -2,14 +2,17 @@ use crate::consts::DEFAULT_FUNCTION_NAMESPACE;
|
|||||||
use crate::handlers::function_get::get_function;
|
use crate::handlers::function_get::get_function;
|
||||||
use actix_web::{Error, error::ErrorInternalServerError};
|
use actix_web::{Error, error::ErrorInternalServerError};
|
||||||
use log;
|
use log;
|
||||||
|
use service::Service;
|
||||||
|
use std::sync::Arc;
|
||||||
use url::Url;
|
use url::Url;
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
pub struct InvokeResolver {
|
pub struct InvokeResolver {
|
||||||
client: service::Service,
|
client: Arc<Service>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl InvokeResolver {
|
impl InvokeResolver {
|
||||||
pub async fn new(client: service::Service) -> Self {
|
pub async fn new(client: Arc<Service>) -> Self {
|
||||||
Self { client }
|
Self { client }
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -17,13 +20,13 @@ impl InvokeResolver {
|
|||||||
//根据函数名和containerd获取函数ip,
|
//根据函数名和containerd获取函数ip,
|
||||||
//从函数名称中提取命名空间。如果函数名称中包含 .,则将其后的部分作为命名空间;否则使用默认命名空间
|
//从函数名称中提取命名空间。如果函数名称中包含 .,则将其后的部分作为命名空间;否则使用默认命名空间
|
||||||
|
|
||||||
let mut actual_function_name = function_name;
|
// let mut actual_function_name = function_name;
|
||||||
let namespace = get_namespace_or_default(function_name, DEFAULT_FUNCTION_NAMESPACE);
|
let namespace = get_namespace_or_default(function_name, DEFAULT_FUNCTION_NAMESPACE);
|
||||||
if function_name.contains('.') {
|
// if function_name.contains('.') {
|
||||||
actual_function_name = function_name.trim_end_matches(&format!(".{}", namespace));
|
// actual_function_name = function_name.trim_end_matches(&format!(".{}", namespace));
|
||||||
}
|
// }
|
||||||
|
|
||||||
let function = match get_function(&self.client, actual_function_name, &namespace).await {
|
let function = match get_function(&self.client, function_name, &namespace).await {
|
||||||
Ok(function) => function,
|
Ok(function) => function,
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
log::error!("Failed to get function:{}", e);
|
log::error!("Failed to get function:{}", e);
|
||||||
@ -31,10 +34,12 @@ impl InvokeResolver {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let ip = function.ip;
|
//容器启动后的port?
|
||||||
let port = 8080;
|
let ip = function.ip.clone();
|
||||||
|
println!("function: {:?}", function);
|
||||||
|
//let port = 80;
|
||||||
|
|
||||||
let urlstr = format!("http://{}:{}", ip, port);
|
let urlstr = format!("http://{}", ip);
|
||||||
match Url::parse(&urlstr) {
|
match Url::parse(&urlstr) {
|
||||||
Ok(url) => Ok(url),
|
Ok(url) => Ok(url),
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
|
@ -19,6 +19,7 @@ pub async fn proxy_handler(
|
|||||||
.expect("empty proxy handler resolver, cannot be nil");
|
.expect("empty proxy handler resolver, cannot be nil");
|
||||||
|
|
||||||
let proxy_client = new_proxy_client_from_config(config.as_ref()).await;
|
let proxy_client = new_proxy_client_from_config(config.as_ref()).await;
|
||||||
|
println!("proxy_client : {:?}", proxy_client);
|
||||||
|
|
||||||
match *req.method() {
|
match *req.method() {
|
||||||
Method::POST
|
Method::POST
|
||||||
|
@ -25,13 +25,13 @@ impl FaaSConfig {
|
|||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
Self {
|
Self {
|
||||||
tcp_port: None,
|
tcp_port: None,
|
||||||
read_timeout: Duration::from_secs(0),
|
read_timeout: Duration::from_secs(10),
|
||||||
write_timeout: Duration::from_secs(0),
|
write_timeout: Duration::from_secs(10),
|
||||||
enable_health: false,
|
enable_health: false,
|
||||||
enable_basic_auth: false,
|
enable_basic_auth: false,
|
||||||
secret_mount_path: String::from("/var/openfaas/secrets"),
|
secret_mount_path: String::from("/var/openfaas/secrets"),
|
||||||
max_idle_conns: 0,
|
max_idle_conns: 0,
|
||||||
max_idle_conns_per_host: 0,
|
max_idle_conns_per_host: 10,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub fn get_read_timeout(&self) -> Duration {
|
pub fn get_read_timeout(&self) -> Duration {
|
||||||
|
@ -177,6 +177,7 @@ impl Service {
|
|||||||
// TASK_EXITED (4) — 任务已退出
|
// TASK_EXITED (4) — 任务已退出
|
||||||
// TASK_PAUSED (5) — 任务已暂停
|
// TASK_PAUSED (5) — 任务已暂停
|
||||||
// TASK_FAILED (6) — 任务失败
|
// TASK_FAILED (6) — 任务失败
|
||||||
|
let _ = self.kill_task(task.id.to_string(), ns).await;
|
||||||
let _ = self.delete_task(&task.id, ns).await;
|
let _ = self.delete_task(&task.id, ns).await;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user