manta_server/service/
ephemeral_env.rs1use csm_rs::ShastaClient;
20use manta_backend_dispatcher::error::Error;
21
22use crate::server::common::app_context::InfraContext;
23use crate::server::common::jwt_ops;
24use crate::wire_conv;
25
26const EPHEMERAL_IMAGE_NAME: &str = "__ephemeral_image";
27
28pub async fn exec(
50 infra: &InfraContext<'_>,
51 token: &str,
52 image_id: &str,
53) -> Result<String, Error> {
54 let user_public_key_name =
55 jwt_ops::get_preferred_username(token).map_err(wire_conv::to_backend)?;
56
57 tracing::info!("Looking for user '{}' public SSH key", user_public_key_name);
58
59 let shasta = ShastaClient::new(
60 infra.shasta_base_url,
61 infra.shasta_root_cert.to_vec(),
62 infra.socks5_proxy.map(|s| s.to_string()),
63 )
64 .map_err(|e| {
65 Error::BadRequest(format!("Could not build Shasta HTTP client: {e}"))
66 })?;
67
68 let user_public_ssh_id = if let Ok(Some(user_public_ssh_key)) = shasta
69 .ims_public_keys_v3_get_single(token, &user_public_key_name)
70 .await
71 {
72 user_public_ssh_key.id.ok_or_else(|| {
73 Error::MissingField(
74 "IMS public-key response missing server-generated 'id'".to_string(),
75 )
76 })?
77 } else {
78 return Err(Error::NotFound(format!(
79 "User '{user_public_key_name}' does not have an SSH public key in Alps. \
80 Please contact platform sys admins."
81 )));
82 };
83
84 tracing::info!("SSH key found with ID {}", user_public_ssh_id);
85 tracing::info!(
86 "Creating ephemeral environment based on image ID {}",
87 image_id
88 );
89
90 let resp_json = shasta
91 .ims_job_post_customize(
92 token,
93 EPHEMERAL_IMAGE_NAME,
94 image_id,
95 &user_public_ssh_id,
96 )
97 .await
98 .map_err(|e| {
99 Error::BadRequest(format!(
100 "Could not create ephemeral environment based on image ID {image_id}: {e}"
101 ))
102 })?;
103
104 let hostname = resp_json
105 .pointer("/ssh_containers/0/connection_info/customer_access/host")
106 .and_then(|v| v.as_str())
107 .ok_or_else(|| {
108 Error::MissingField(
109 "Failed to get SSH container hostname from ephemeral env response"
110 .to_string(),
111 )
112 })?
113 .to_string();
114
115 tracing::info!("Ephemeral environment created — SSH hostname: {}", hostname);
116
117 Ok(hostname)
118}