|
17 | 17 | use ::rpc::forge as rpc; |
18 | 18 | use carbide_uuid::machine::MachineId; |
19 | 19 | use itertools::Itertools; |
20 | | -use model::machine::LoadSnapshotOptions; |
| 20 | +use model::machine::{ |
| 21 | + HostReprovisionState, LoadSnapshotOptions, ManagedHostState, ScoutUpgradeResult, |
| 22 | +}; |
21 | 23 | use tonic::{Request, Response, Status}; |
22 | 24 |
|
23 | 25 | use crate::CarbideError; |
24 | | -use crate::api::{Api, log_request_data}; |
| 26 | +use crate::api::{Api, log_request_data, truncate}; |
25 | 27 | use crate::handlers::utils::convert_and_log_machine_id; |
26 | 28 |
|
27 | 29 | pub(crate) async fn reset_host_reprovisioning( |
@@ -144,3 +146,72 @@ pub async fn mark_manual_firmware_upgrade_complete( |
144 | 146 |
|
145 | 147 | Ok(Response::new(())) |
146 | 148 | } |
| 149 | + |
| 150 | +pub async fn report_scout_firmware_upgrade_status( |
| 151 | + api: &Api, |
| 152 | + request: Request<rpc::ScoutFirmwareUpgradeStatusRequest>, |
| 153 | +) -> Result<Response<()>, Status> { |
| 154 | + log_request_data(&request); |
| 155 | + |
| 156 | + let req = request.into_inner(); |
| 157 | + let machine_id = convert_and_log_machine_id(req.machine_id.as_ref())?; |
| 158 | + |
| 159 | + let (machine, mut txn) = api.load_machine(&machine_id, Default::default()).await?; |
| 160 | + |
| 161 | + // Verify machine is in WaitingForScoutUpgrade state |
| 162 | + let (component_type, target_version, started_at, retry_count) = match machine.current_state() { |
| 163 | + ManagedHostState::HostReprovision { |
| 164 | + reprovision_state: |
| 165 | + HostReprovisionState::WaitingForScoutUpgrade { |
| 166 | + component_type, |
| 167 | + target_version, |
| 168 | + started_at, |
| 169 | + .. |
| 170 | + }, |
| 171 | + retry_count, |
| 172 | + } => ( |
| 173 | + component_type.clone(), |
| 174 | + target_version.clone(), |
| 175 | + *started_at, |
| 176 | + *retry_count, |
| 177 | + ), |
| 178 | + _ => { |
| 179 | + return Err(CarbideError::InvalidArgument(format!( |
| 180 | + "Machine {machine_id} is not in WaitingForScoutUpgrade state" |
| 181 | + )) |
| 182 | + .into()); |
| 183 | + } |
| 184 | + }; |
| 185 | + |
| 186 | + const MAX_STORED_OUTPUT_SIZE: usize = 1500; |
| 187 | + |
| 188 | + let new_state = ManagedHostState::HostReprovision { |
| 189 | + reprovision_state: HostReprovisionState::WaitingForScoutUpgrade { |
| 190 | + component_type, |
| 191 | + target_version, |
| 192 | + started_at, |
| 193 | + result: Some(ScoutUpgradeResult { |
| 194 | + success: req.success, |
| 195 | + exit_code: req.exit_code, |
| 196 | + stdout: truncate(req.stdout, MAX_STORED_OUTPUT_SIZE), |
| 197 | + stderr: truncate(req.stderr, MAX_STORED_OUTPUT_SIZE), |
| 198 | + error: truncate(req.error, MAX_STORED_OUTPUT_SIZE), |
| 199 | + }), |
| 200 | + }, |
| 201 | + retry_count, |
| 202 | + }; |
| 203 | + |
| 204 | + db::machine::advance(&machine, &mut txn, &new_state, None).await?; |
| 205 | + |
| 206 | + txn.commit().await?; |
| 207 | + |
| 208 | + if let Err(err) = api |
| 209 | + .machine_state_handler_enqueuer |
| 210 | + .enqueue_object(&machine_id) |
| 211 | + .await |
| 212 | + { |
| 213 | + tracing::warn!(%err, %machine_id, "Failed to wake up state handler for machine"); |
| 214 | + } |
| 215 | + |
| 216 | + Ok(Response::new(())) |
| 217 | +} |
0 commit comments