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:
dolzhuying 2025-04-12 13:26:13 +08:00 committed by Samuel Dai
parent 7258f4f6ed
commit 92b281dc48
8 changed files with 35 additions and 23 deletions

View File

@ -8,8 +8,9 @@ pub mod types;
use handlers::*;
use provider::{
handlers::{delete::delete_handler, deploy::deploy_handler},
handlers::{delete::delete_handler, deploy::deploy_handler, invoke_resolver::InvokeResolver},
proxy::proxy_handler::proxy_handler,
types::config::FaaSConfig,
};
#[actix_web::main]
@ -21,11 +22,16 @@ async fn main() -> std::io::Result<()> {
.unwrap(),
);
let resolver = Some(InvokeResolver::new(service.clone()).await);
let faas_config = FaaSConfig::new();
println!("I'm running!");
let server = HttpServer::new(move || {
App::new()
.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("/remove-container", web::post().to(remove_container))
.route("/containers", web::get().to(get_container_list))

View File

@ -5,7 +5,7 @@ use crate::{
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 service::Service;
use std::sync::Arc;
@ -24,10 +24,7 @@ pub async fn delete_handler(
Ok(()) => {
HttpResponse::Ok().body(format!("function {} deleted successfully", function_name))
}
Err(e) => HttpResponse::InternalServerError().body(format!(
"failed to delete function {} in namespace {} because {}",
function_name, namespace, e
)),
Err(e) => e.error_response(),
}
}

View File

@ -1,7 +1,8 @@
use crate::handlers::function_list::Function;
// use service::spec::{ Mount, Spec};
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;
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(
client: &service::Service,
service: &Arc<Service>,
function_name: &str,
namespace: &str,
) -> Result<Function, FunctionError> {
let cid = function_name;
let ip = client.get_ip(cid).await.unwrap();
let container = client
let container = service
.load_container(cid, namespace)
.await
.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 created_at = UNIX_EPOCH + Duration::new(timestamp.seconds, timestamp.nanos);
let task = client
let task = service
.get_task(cid, namespace)
.await
.map_err(|e| FunctionError::FunctionNotFound(e.to_string()));

View File

@ -1,5 +1,6 @@
use std::{collections::HashMap, time::SystemTime};
#[derive(Debug)]
pub struct Function {
pub name: String,
pub namespace: String,

View File

@ -2,14 +2,17 @@ use crate::consts::DEFAULT_FUNCTION_NAMESPACE;
use crate::handlers::function_get::get_function;
use actix_web::{Error, error::ErrorInternalServerError};
use log;
use service::Service;
use std::sync::Arc;
use url::Url;
#[derive(Clone)]
pub struct InvokeResolver {
client: service::Service,
client: Arc<Service>,
}
impl InvokeResolver {
pub async fn new(client: service::Service) -> Self {
pub async fn new(client: Arc<Service>) -> Self {
Self { client }
}
@ -17,13 +20,13 @@ impl InvokeResolver {
//根据函数名和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);
if function_name.contains('.') {
actual_function_name = function_name.trim_end_matches(&format!(".{}", namespace));
}
// if function_name.contains('.') {
// 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,
Err(e) => {
log::error!("Failed to get function:{}", e);
@ -31,10 +34,12 @@ impl InvokeResolver {
}
};
let ip = function.ip;
let port = 8080;
//容器启动后的port?
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) {
Ok(url) => Ok(url),
Err(e) => {

View File

@ -19,6 +19,7 @@ pub async fn proxy_handler(
.expect("empty proxy handler resolver, cannot be nil");
let proxy_client = new_proxy_client_from_config(config.as_ref()).await;
println!("proxy_client : {:?}", proxy_client);
match *req.method() {
Method::POST

View File

@ -25,13 +25,13 @@ impl FaaSConfig {
pub fn new() -> Self {
Self {
tcp_port: None,
read_timeout: Duration::from_secs(0),
write_timeout: Duration::from_secs(0),
read_timeout: Duration::from_secs(10),
write_timeout: Duration::from_secs(10),
enable_health: false,
enable_basic_auth: false,
secret_mount_path: String::from("/var/openfaas/secrets"),
max_idle_conns: 0,
max_idle_conns_per_host: 0,
max_idle_conns_per_host: 10,
}
}
pub fn get_read_timeout(&self) -> Duration {

View File

@ -177,6 +177,7 @@ impl Service {
// TASK_EXITED (4) — 任务已退出
// TASK_PAUSED (5) — 任务已暂停
// TASK_FAILED (6) — 任务失败
let _ = self.kill_task(task.id.to_string(), ns).await;
let _ = self.delete_task(&task.id, ns).await;
}