manta_server/service/
ephemeral_env.rs1use csm_rs::ShastaClient;
6use manta_backend_dispatcher::error::Error;
7
8use crate::server::common::app_context::InfraContext;
9use crate::server::common::jwt_ops;
10use crate::wire_conv;
11
12const EPHEMERAL_IMAGE_NAME: &str = "__ephemeral_image";
13
14pub async fn exec(
25 infra: &InfraContext<'_>,
26 token: &str,
27 image_id: &str,
28) -> Result<String, Error> {
29 let user_public_key_name =
30 jwt_ops::get_preferred_username(token).map_err(wire_conv::to_backend)?;
31
32 tracing::info!("Looking for user '{}' public SSH key", user_public_key_name);
33
34 let shasta = ShastaClient::new(
35 infra.shasta_base_url,
36 infra.shasta_root_cert.to_vec(),
37 infra.socks5_proxy.map(|s| s.to_string()),
38 )
39 .map_err(|e| {
40 Error::BadRequest(format!("Could not build Shasta HTTP client: {e}"))
41 })?;
42
43 let user_public_ssh_id = if let Ok(Some(user_public_ssh_key)) = shasta
44 .ims_public_keys_v3_get_single(token, &user_public_key_name)
45 .await
46 {
47 user_public_ssh_key.id.ok_or_else(|| {
48 Error::MissingField(
49 "IMS public-key response missing server-generated 'id'".to_string(),
50 )
51 })?
52 } else {
53 return Err(Error::NotFound(format!(
54 "User '{user_public_key_name}' does not have an SSH public key in Alps. \
55 Please contact platform sys admins."
56 )));
57 };
58
59 tracing::info!("SSH key found with ID {}", user_public_ssh_id);
60 tracing::info!(
61 "Creating ephemeral environment based on image ID {}",
62 image_id
63 );
64
65 let resp_json = shasta
66 .ims_job_post_customize(
67 token,
68 EPHEMERAL_IMAGE_NAME,
69 image_id,
70 &user_public_ssh_id,
71 )
72 .await
73 .map_err(|e| {
74 Error::BadRequest(format!(
75 "Could not create ephemeral environment based on image ID {image_id}: {e}"
76 ))
77 })?;
78
79 let hostname = resp_json
80 .pointer("/ssh_containers/0/connection_info/customer_access/host")
81 .and_then(|v| v.as_str())
82 .ok_or_else(|| {
83 Error::MissingField(
84 "Failed to get SSH container hostname from ephemeral env response"
85 .to_string(),
86 )
87 })?
88 .to_string();
89
90 tracing::info!("Ephemeral environment created — SSH hostname: {}", hostname);
91
92 Ok(hostname)
93}