use std::time::Duration;
use crate::client::Client;
use crate::error::SailError;
use crate::exec::{ExecOptions, ExecProcess};
use crate::sailbox::api::UpgradeResult;
use crate::sailbox::ssh::{EnableSshOptions, SshEndpoint};
use crate::sailbox::types::{
CheckpointOptions, IngressProtocol, SailboxCheckpoint, SailboxHandle, SailboxInfo,
};
use crate::worker::{FileReader, FileWriter, Listener, WriteOptions};
#[derive(Clone)]
pub struct Sailbox {
client: Client,
handle: SailboxHandle,
}
impl std::fmt::Debug for Sailbox {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("Sailbox")
.field("sailbox_id", &self.handle.sailbox_id)
.finish_non_exhaustive()
}
}
impl Sailbox {
pub(crate) fn bind(client: Client, handle: SailboxHandle) -> Sailbox {
Sailbox { client, handle }
}
pub(crate) fn client(&self) -> &Client {
&self.client
}
pub fn sailbox_id(&self) -> &str {
&self.handle.sailbox_id
}
pub fn handle(&self) -> &SailboxHandle {
&self.handle
}
pub fn into_handle(self) -> SailboxHandle {
self.handle
}
pub async fn info(&self) -> Result<SailboxInfo, SailError> {
self.client.get_sailbox(self.sailbox_id()).await
}
pub async fn terminate(&self) -> Result<(), SailError> {
self.client.terminate_sailbox(self.sailbox_id()).await
}
pub async fn pause(&self) -> Result<(), SailError> {
self.client.pause_sailbox(self.sailbox_id()).await
}
pub async fn sleep(&self) -> Result<(), SailError> {
self.client.sleep_sailbox(self.sailbox_id()).await
}
pub async fn resume(&self) -> Result<(), SailError> {
self.client
.resume_sailbox(self.sailbox_id())
.await
.map(|_| ())
}
pub async fn checkpoint(
&self,
options: CheckpointOptions,
) -> Result<SailboxCheckpoint, SailError> {
self.client
.checkpoint_sailbox(
self.sailbox_id(),
options.name.as_deref(),
options.ttl.map(|ttl| ttl.as_secs() as i64),
)
.await
}
pub async fn upgrade(&self) -> Result<UpgradeResult, SailError> {
self.client.upgrade_sailbox(self.sailbox_id()).await
}
pub async fn exec(
&self,
argv: Vec<String>,
options: ExecOptions,
) -> Result<ExecProcess, SailError> {
self.client.exec(self.sailbox_id(), argv, options).await
}
pub async fn exec_shell(
&self,
command: &str,
options: ExecOptions,
) -> Result<ExecProcess, SailError> {
self.client
.exec_shell(self.sailbox_id(), command, options)
.await
}
pub async fn read(&self, path: &str) -> Result<Vec<u8>, SailError> {
self.client.read_file(self.sailbox_id(), path).await
}
pub async fn write(
&self,
path: &str,
data: &[u8],
options: WriteOptions,
) -> Result<(), SailError> {
self.client
.write_file(self.sailbox_id(), path, data, options)
.await
}
pub async fn read_stream(&self, path: &str) -> Result<FileReader, SailError> {
self.client.read_stream(self.sailbox_id(), path).await
}
pub async fn write_stream(
&self,
path: &str,
options: WriteOptions,
) -> Result<FileWriter, SailError> {
self.client
.write_stream(self.sailbox_id(), path, options)
.await
}
pub async fn expose(
&self,
guest_port: u32,
protocol: IngressProtocol,
allowlist: &[String],
) -> Result<Listener, SailError> {
self.client
.expose_listener(self.sailbox_id(), guest_port, protocol, allowlist)
.await
}
pub async fn unexpose(&self, guest_port: u32) -> Result<(), SailError> {
self.client
.unexpose_listener(self.sailbox_id(), guest_port)
.await
}
pub async fn listeners(&self) -> Result<Vec<Listener>, SailError> {
self.client.list_listeners(self.sailbox_id()).await
}
pub async fn listener(&self, guest_port: u32) -> Result<Listener, SailError> {
self.client
.get_listener(self.sailbox_id(), guest_port)
.await
}
pub async fn wait_for_listener(
&self,
guest_port: u32,
timeout: Duration,
poll_interval: Duration,
) -> Result<Listener, SailError> {
self.client
.wait_for_listener(self.sailbox_id(), guest_port, timeout, poll_interval)
.await
}
pub async fn ingress_auth_headers(&self) -> Result<Vec<(String, String)>, SailError> {
self.client.ingress_auth_headers(self.sailbox_id()).await
}
pub async fn enable_ssh(
&self,
options: EnableSshOptions,
) -> Result<Option<SshEndpoint>, SailError> {
self.client
.enable_ssh(
self.sailbox_id(),
&options.allowlist,
options.wait,
options.timeout,
)
.await
}
}
impl Client {
pub fn sailbox(&self, sailbox_id: impl Into<String>) -> Sailbox {
Sailbox {
client: self.clone(),
handle: SailboxHandle {
sailbox_id: sailbox_id.into(),
..Default::default()
},
}
}
}