use crate::agent::{AgentWorkspace, PreparedAgentWorkspace};
use crate::codec::host_service::{HostServiceChannel, connect_host_service, plain_channel};
use crate::codec::runtime_provider::{
from_wire_append_runtime_logs_response, from_wire_hosted_app,
from_wire_list_runtime_sessions_response, from_wire_prepare_runtime_workspace_response,
from_wire_runtime_session, from_wire_runtime_support, to_wire_append_runtime_logs_request,
to_wire_get_runtime_session_request, to_wire_list_runtime_sessions_request,
to_wire_prepare_runtime_workspace_request, to_wire_remove_runtime_workspace_request,
to_wire_start_hosted_app_request, to_wire_start_runtime_session_request,
to_wire_stop_runtime_session_request,
};
use crate::generated::v1;
use crate::rpc_support::GestaltError;
pub type RuntimeEgressMode = i32;
pub mod runtime_egress_mode {
pub const RUNTIME_EGRESS_MODE_UNSPECIFIED: i32 = 0;
pub const RUNTIME_EGRESS_MODE_NONE: i32 = 1;
pub const RUNTIME_EGRESS_MODE_CIDR: i32 = 2;
pub const RUNTIME_EGRESS_MODE_HOSTNAME: i32 = 3;
}
pub type RuntimeLogStream = i32;
pub mod runtime_log_stream {
pub const RUNTIME_LOG_STREAM_UNSPECIFIED: i32 = 0;
pub const RUNTIME_LOG_STREAM_STDOUT: i32 = 1;
pub const RUNTIME_LOG_STREAM_STDERR: i32 = 2;
pub const RUNTIME_LOG_STREAM_RUNTIME: i32 = 3;
}
#[derive(Clone, Debug, Default, PartialEq)]
pub struct AppendRuntimeLogsRequest {
pub session_id: String,
pub logs: Vec<RuntimeLogEntry>,
}
#[derive(Clone, Debug, Default, PartialEq)]
pub struct AppendRuntimeLogsResponse {
pub last_seq: i64,
}
#[derive(Clone, Debug, Default, PartialEq)]
pub struct GetRuntimeSessionRequest {
pub session_id: String,
}
#[derive(Clone, Debug, Default, PartialEq)]
pub struct HostedApp {
pub id: String,
pub session_id: String,
pub app_name: String,
pub dial_target: String,
}
#[derive(Clone, Debug, Default, PartialEq)]
pub struct ListRuntimeSessionsRequest {
pub page_size: i32,
pub page_token: String,
}
#[derive(Clone, Debug, Default, PartialEq)]
pub struct ListRuntimeSessionsResponse {
pub sessions: Vec<RuntimeSession>,
pub next_page_token: String,
}
#[derive(Clone, Debug, Default, PartialEq)]
pub struct PrepareRuntimeWorkspaceRequest {
pub session_id: String,
pub agent_session_id: String,
pub workspace: Option<AgentWorkspace>,
}
#[derive(Clone, Debug, Default, PartialEq)]
pub struct PrepareRuntimeWorkspaceResponse {
pub workspace: Option<PreparedAgentWorkspace>,
}
#[derive(Clone, Debug, Default, PartialEq)]
pub struct RemoveRuntimeWorkspaceRequest {
pub session_id: String,
pub agent_session_id: String,
}
#[derive(Clone, Debug, Default, PartialEq)]
pub struct RuntimeImagePullAuth {
pub docker_config_json: String,
}
#[derive(Clone, Debug, Default, PartialEq)]
pub struct RuntimeLogEntry {
pub stream: RuntimeLogStream,
pub message: String,
pub observed_at: Option<std::time::SystemTime>,
pub source_seq: i64,
}
#[derive(Clone, Debug, Default, PartialEq)]
pub struct RuntimeSession {
pub id: String,
pub state: String,
pub metadata: std::collections::BTreeMap<String, String>,
pub lifecycle: Option<RuntimeSessionLifecycle>,
pub state_reason: String,
pub state_message: String,
}
#[derive(Clone, Debug, Default, PartialEq)]
pub struct RuntimeSessionLifecycle {
pub started_at: Option<std::time::SystemTime>,
pub recommended_drain_at: Option<std::time::SystemTime>,
pub expires_at: Option<std::time::SystemTime>,
}
#[derive(Clone, Debug, Default, PartialEq)]
pub struct RuntimeSupport {
pub can_host_apps: bool,
pub egress_mode: RuntimeEgressMode,
pub supports_prepare_workspace: bool,
}
#[derive(Clone, Debug, Default, PartialEq)]
pub struct StartHostedAppRequest {
pub session_id: String,
pub app_name: String,
pub command: String,
pub args: Vec<String>,
pub env: std::collections::BTreeMap<String, String>,
pub allowed_hosts: Vec<String>,
pub default_action: String,
pub host_binary: String,
pub workdir: String,
}
#[derive(Clone, Debug, Default, PartialEq)]
pub struct StartRuntimeSessionRequest {
pub app_name: String,
pub template: String,
pub image: String,
pub metadata: std::collections::BTreeMap<String, String>,
pub image_pull_auth: Option<RuntimeImagePullAuth>,
}
#[derive(Clone, Debug, Default, PartialEq)]
pub struct StopRuntimeSessionRequest {
pub session_id: String,
}
pub struct Runtime {
inner: v1::runtime_client::RuntimeClient<tonic::transport::Channel>,
timeout: Option<std::time::Duration>,
}
impl Runtime {
pub fn new(channel: tonic::transport::Channel) -> Self {
Self {
inner: v1::runtime_client::RuntimeClient::new(channel),
timeout: None,
}
}
pub fn with_timeout(mut self, timeout: std::time::Duration) -> Self {
self.timeout = Some(timeout);
self
}
pub async fn get_support(&mut self) -> Result<RuntimeSupport, GestaltError> {
let mut tonic_request = tonic::Request::new(());
if let Some(timeout) = self.timeout {
tonic_request.set_timeout(timeout);
}
let response = self.inner.get_support(tonic_request).await?;
Ok(from_wire_runtime_support(response.into_inner()))
}
pub async fn start_session(
&mut self,
app_name: String,
template: String,
image: String,
image_pull_auth: Option<RuntimeImagePullAuth>,
) -> Result<RuntimeSession, GestaltError> {
let request = StartRuntimeSessionRequest {
app_name,
template,
image,
image_pull_auth,
..Default::default()
};
let mut tonic_request = tonic::Request::new(to_wire_start_runtime_session_request(request));
if let Some(timeout) = self.timeout {
tonic_request.set_timeout(timeout);
}
let response = self.inner.start_session(tonic_request).await?;
Ok(from_wire_runtime_session(response.into_inner()))
}
pub async fn start_session_raw(
&mut self,
request: StartRuntimeSessionRequest,
) -> Result<RuntimeSession, GestaltError> {
let mut tonic_request = tonic::Request::new(to_wire_start_runtime_session_request(request));
if let Some(timeout) = self.timeout {
tonic_request.set_timeout(timeout);
}
let response = self.inner.start_session(tonic_request).await?;
Ok(from_wire_runtime_session(response.into_inner()))
}
pub async fn get_session(
&mut self,
session_id: String,
) -> Result<RuntimeSession, GestaltError> {
let request = GetRuntimeSessionRequest { session_id };
let mut tonic_request = tonic::Request::new(to_wire_get_runtime_session_request(request));
if let Some(timeout) = self.timeout {
tonic_request.set_timeout(timeout);
}
let response = self.inner.get_session(tonic_request).await?;
Ok(from_wire_runtime_session(response.into_inner()))
}
pub async fn get_session_raw(
&mut self,
request: GetRuntimeSessionRequest,
) -> Result<RuntimeSession, GestaltError> {
let mut tonic_request = tonic::Request::new(to_wire_get_runtime_session_request(request));
if let Some(timeout) = self.timeout {
tonic_request.set_timeout(timeout);
}
let response = self.inner.get_session(tonic_request).await?;
Ok(from_wire_runtime_session(response.into_inner()))
}
pub async fn list_sessions(
&mut self,
request: ListRuntimeSessionsRequest,
) -> Result<ListRuntimeSessionsResponse, GestaltError> {
let mut tonic_request = tonic::Request::new(to_wire_list_runtime_sessions_request(request));
if let Some(timeout) = self.timeout {
tonic_request.set_timeout(timeout);
}
let response = self.inner.list_sessions(tonic_request).await?;
Ok(from_wire_list_runtime_sessions_response(
response.into_inner(),
))
}
pub async fn stop_session(&mut self, session_id: String) -> Result<(), GestaltError> {
let request = StopRuntimeSessionRequest { session_id };
let mut tonic_request = tonic::Request::new(to_wire_stop_runtime_session_request(request));
if let Some(timeout) = self.timeout {
tonic_request.set_timeout(timeout);
}
self.inner.stop_session(tonic_request).await?;
Ok(())
}
pub async fn stop_session_raw(
&mut self,
request: StopRuntimeSessionRequest,
) -> Result<(), GestaltError> {
let mut tonic_request = tonic::Request::new(to_wire_stop_runtime_session_request(request));
if let Some(timeout) = self.timeout {
tonic_request.set_timeout(timeout);
}
self.inner.stop_session(tonic_request).await?;
Ok(())
}
pub async fn prepare_workspace(
&mut self,
session_id: String,
agent_session_id: String,
workspace: Option<AgentWorkspace>,
) -> Result<Option<PreparedAgentWorkspace>, GestaltError> {
let request = PrepareRuntimeWorkspaceRequest {
session_id,
agent_session_id,
workspace,
};
let mut tonic_request =
tonic::Request::new(to_wire_prepare_runtime_workspace_request(request));
if let Some(timeout) = self.timeout {
tonic_request.set_timeout(timeout);
}
let response = from_wire_prepare_runtime_workspace_response(
self.inner
.prepare_workspace(tonic_request)
.await?
.into_inner(),
);
Ok(response.workspace)
}
pub async fn prepare_workspace_raw(
&mut self,
request: PrepareRuntimeWorkspaceRequest,
) -> Result<PrepareRuntimeWorkspaceResponse, GestaltError> {
let mut tonic_request =
tonic::Request::new(to_wire_prepare_runtime_workspace_request(request));
if let Some(timeout) = self.timeout {
tonic_request.set_timeout(timeout);
}
let response = self.inner.prepare_workspace(tonic_request).await?;
Ok(from_wire_prepare_runtime_workspace_response(
response.into_inner(),
))
}
pub async fn remove_workspace(
&mut self,
session_id: String,
agent_session_id: String,
) -> Result<(), GestaltError> {
let request = RemoveRuntimeWorkspaceRequest {
session_id,
agent_session_id,
};
let mut tonic_request =
tonic::Request::new(to_wire_remove_runtime_workspace_request(request));
if let Some(timeout) = self.timeout {
tonic_request.set_timeout(timeout);
}
self.inner.remove_workspace(tonic_request).await?;
Ok(())
}
pub async fn remove_workspace_raw(
&mut self,
request: RemoveRuntimeWorkspaceRequest,
) -> Result<(), GestaltError> {
let mut tonic_request =
tonic::Request::new(to_wire_remove_runtime_workspace_request(request));
if let Some(timeout) = self.timeout {
tonic_request.set_timeout(timeout);
}
self.inner.remove_workspace(tonic_request).await?;
Ok(())
}
#[allow(clippy::too_many_arguments)]
pub async fn start_app(
&mut self,
session_id: String,
app_name: String,
command: String,
args: Vec<String>,
allowed_hosts: Vec<String>,
default_action: String,
host_binary: String,
workdir: String,
) -> Result<HostedApp, GestaltError> {
let request = StartHostedAppRequest {
session_id,
app_name,
command,
args,
allowed_hosts,
default_action,
host_binary,
workdir,
..Default::default()
};
let mut tonic_request = tonic::Request::new(to_wire_start_hosted_app_request(request));
if let Some(timeout) = self.timeout {
tonic_request.set_timeout(timeout);
}
let response = self.inner.start_app(tonic_request).await?;
Ok(from_wire_hosted_app(response.into_inner()))
}
pub async fn start_app_raw(
&mut self,
request: StartHostedAppRequest,
) -> Result<HostedApp, GestaltError> {
let mut tonic_request = tonic::Request::new(to_wire_start_hosted_app_request(request));
if let Some(timeout) = self.timeout {
tonic_request.set_timeout(timeout);
}
let response = self.inner.start_app(tonic_request).await?;
Ok(from_wire_hosted_app(response.into_inner()))
}
}
pub struct RuntimeLogHost {
inner: v1::runtime_log_host_client::RuntimeLogHostClient<HostServiceChannel>,
timeout: Option<std::time::Duration>,
}
impl RuntimeLogHost {
pub fn new(channel: tonic::transport::Channel) -> Self {
Self {
inner: v1::runtime_log_host_client::RuntimeLogHostClient::new(plain_channel(channel)),
timeout: None,
}
}
pub fn with_timeout(mut self, timeout: std::time::Duration) -> Self {
self.timeout = Some(timeout);
self
}
pub async fn connect() -> Result<Self, GestaltError> {
Self::connect_named("").await
}
pub async fn connect_named(name: &str) -> Result<Self, GestaltError> {
Ok(Self {
inner: v1::runtime_log_host_client::RuntimeLogHostClient::new(
connect_host_service("runtime log host", name).await?,
),
timeout: None,
})
}
pub async fn append_logs(
&mut self,
session_id: String,
logs: Vec<RuntimeLogEntry>,
) -> Result<i64, GestaltError> {
let request = AppendRuntimeLogsRequest { session_id, logs };
let mut tonic_request = tonic::Request::new(to_wire_append_runtime_logs_request(request));
if let Some(timeout) = self.timeout {
tonic_request.set_timeout(timeout);
}
let response = from_wire_append_runtime_logs_response(
self.inner.append_logs(tonic_request).await?.into_inner(),
);
Ok(response.last_seq)
}
pub async fn append_logs_raw(
&mut self,
request: AppendRuntimeLogsRequest,
) -> Result<AppendRuntimeLogsResponse, GestaltError> {
let mut tonic_request = tonic::Request::new(to_wire_append_runtime_logs_request(request));
if let Some(timeout) = self.timeout {
tonic_request.set_timeout(timeout);
}
let response = self.inner.append_logs(tonic_request).await?;
Ok(from_wire_append_runtime_logs_response(
response.into_inner(),
))
}
}