runtime-rs: shim management client

Add client side function(public), to establish http connections (PUT,
POST, GET) to the long standing shim mgmt server.

Fixes: #5114
Signed-off-by: Ji-Xinyou <jerryji0414@outlook.com>
This commit is contained in:
Ji-Xinyou 2022-09-07 15:39:14 +08:00
parent e891295e10
commit 9f13496e13
5 changed files with 87 additions and 3 deletions

View File

@ -12,6 +12,7 @@ slog = "2.5.2"
slog-scope = "4.4.0"
tokio = { version = "1.8.0", features = ["rt-multi-thread"] }
hyper = { version = "0.14.20", features = ["stream", "server", "http1"] }
hyperlocal = "0.8"
common = { path = "./common" }
kata-types = { path = "../../../libs/kata-types" }

View File

@ -12,4 +12,5 @@ logging::logger_with_subsystem!(sl, "runtimes");
pub mod manager;
pub use manager::RuntimeHandlerManager;
mod shim_mgmt;
pub use shim_mgmt::client::MgmtClient;
mod static_resource;

View File

@ -8,7 +8,10 @@ use std::sync::Arc;
use anyhow::{anyhow, Context, Result};
use crate::{shim_mgmt::server::MgmtServer, static_resource::StaticResourceManager};
use crate::{
shim_mgmt::server::MgmtServer,
static_resource::StaticResourceManager,
};
use common::{
message::Message,
types::{Request, Response},

View File

@ -2,4 +2,78 @@
// Copyright (c) 2019-2022 Ant Group
//
// SPDX-License-Identifier: Apache-2.0
//
//
#![allow(dead_code)]
// Defines the general client functions used by other components acting like
// clients. To be specific, a client first connect to the socket, then send
// request to destined URL, and finally handle the request(or not)
use std::{path::Path, path::PathBuf, time::Duration};
use super::server::mgmt_socket_addr;
use anyhow::{Context, Result};
use hyper::{Body, Client, Method, Request, Response};
use hyperlocal::{UnixClientExt, UnixConnector, Uri};
/// Shim management client with timeout
pub struct MgmtClient {
/// The socket *file path* on host file system
s_path: PathBuf,
/// The http client connect to the long standing shim mgmt server
client: Client<UnixConnector, Body>,
/// timeout value for each dial
timeout: Option<Duration>,
}
impl MgmtClient {
/// Construct a new client connecting to shim mgmt server
pub fn new(sid: String, timeout: Option<Duration>) -> Result<Self> {
let unix_socket_path = mgmt_socket_addr(sid);
let s_addr = unix_socket_path
.strip_prefix("unix:")
.context("failed to strix prefix")?;
let s_path = Path::new("/").join(s_addr).as_path().to_owned();
let client = Client::unix();
Ok(Self {
s_path,
client,
timeout,
})
}
/// The http GET method for client, return a raw response. Further handling should be done by caller.
/// Parameter uri should be like "/agent-url" etc.
pub async fn get(&self, uri: &str) -> Result<Response<Body>> {
let url: hyper::Uri = Uri::new(&self.s_path, uri).into();
let response = self.client.get(url).await.context("failed to GET")?;
Ok(response)
}
/// The http PUT method for client
pub async fn put(&self, uri: &str) -> Result<Response<Body>> {
let url: hyper::Uri = Uri::new(&self.s_path, uri).into();
let req = Request::builder()
.method(Method::PUT)
.uri(url)
.body(Body::from(""))
.expect("request builder");
let response = self.client.request(req).await?;
Ok(response)
}
/// The http POST method for client
pub async fn post(&self, uri: &str) -> Result<Response<Body>> {
let url: hyper::Uri = Uri::new(&self.s_path, uri).into();
let req = Request::builder()
.method(Method::POST)
.uri(url)
.body(Body::from(""))
.expect("request builder");
let response = self.client.request(req).await?;
Ok(response)
}
}

View File

@ -19,7 +19,12 @@ pub(crate) async fn handler_mux(
sandbox: Arc<dyn Sandbox>,
req: Request<Body>,
) -> Result<Response<Body>> {
info!(sl!(), "mgmt-svr(mux): recv req {:?}", req);
info!(
sl!(),
"mgmt-svr(mux): recv req, method: {}, uri: {}",
req.method(),
req.uri().path()
);
match (req.method(), req.uri().path()) {
(&Method::GET, AGENT_URL) => agent_url_handler(sandbox, req).await,
_ => Ok(not_found(req).await),