use std::time::Duration;
use serde_json::json;
use crate::errors::RuntimeError;
use crate::http_client::{http_json, http_json_with_timeout};
use crate::spawn_credential::{
SpawnApproval, SpawnCredential, SPAWN_APPROVAL_HEADER, SPAWN_CREDENTIAL_HEADER,
};
const HEALTH_TIMEOUT: Duration = Duration::from_secs(2);
pub fn check_roost_health(roost_url: &str) -> Result<(), String> {
let roost_url = roost_url.trim_end_matches('/');
http_json_with_timeout(
"GET",
&format!("{roost_url}/health"),
None,
&[],
HEALTH_TIMEOUT,
)
.map(|_| ())
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum SessionOutcome {
Complete,
Failed,
}
impl SessionOutcome {
pub fn as_str(self) -> &'static str {
match self {
Self::Complete => "complete",
Self::Failed => "failed",
}
}
}
pub fn register_session(
roost_url: &str,
session_id: &str,
capsule_name: &str,
capsule_version: &str,
grant: Option<&SpawnApproval>,
) -> Result<SpawnCredential, RuntimeError> {
let roost_url = roost_url.trim_end_matches('/');
let body = json!({
"session_id": session_id,
"name": capsule_name,
"version": capsule_version,
})
.to_string();
let headers: Vec<(&str, &str)> = match grant {
Some(grant) => vec![(SPAWN_APPROVAL_HEADER, grant.expose())],
None => Vec::new(),
};
let response = http_json(
"POST",
&format!("{roost_url}/register"),
Some(&body),
&headers,
)
.map_err(|reason| RuntimeError::SpawnRegistrationFailed {
roost_url: roost_url.to_string(),
reason,
})?;
let credential = response
.get("credential")
.and_then(serde_json::Value::as_str)
.ok_or_else(|| RuntimeError::SpawnRegistrationFailed {
roost_url: roost_url.to_string(),
reason: "the register response carried no credential".to_string(),
})?;
Ok(SpawnCredential::new(credential.to_string()))
}
pub fn deregister_session(roost_url: &str, credential: &SpawnCredential, outcome: SessionOutcome) {
let roost_url = roost_url.trim_end_matches('/');
let body = json!({ "outcome": outcome.as_str() }).to_string();
if let Err(reason) = http_json(
"POST",
&format!("{roost_url}/deregister"),
Some(&body),
&[(SPAWN_CREDENTIAL_HEADER, credential.expose())],
) {
eprintln!("[capsule-runtime] could not deregister from mur-roost at {roost_url}: {reason}");
}
}