Skip to content

Commit 2a9af3b

Browse files
authored
[reconfigurator] Extract SP related planning code into its own submodule (#8826)
This is just extracting code and moving it to another file. No changes have been made. Follow up to #8421 (comment)
1 parent a9a7477 commit 2a9af3b

File tree

2 files changed

+192
-170
lines changed
  • nexus/reconfigurator/planning/src/mgs_updates

2 files changed

+192
-170
lines changed

nexus/reconfigurator/planning/src/mgs_updates/mod.rs

Lines changed: 4 additions & 170 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,13 @@
55
//! Facilities for making choices about MGS-managed updates
66
77
mod rot;
8+
mod sp;
89

910
use crate::mgs_updates::rot::RotUpdateState;
1011
use crate::mgs_updates::rot::mgs_update_status_rot;
1112
use crate::mgs_updates::rot::try_make_update_rot;
13+
use crate::mgs_updates::sp::mgs_update_status_sp;
14+
use crate::mgs_updates::sp::try_make_update_sp;
1215

1316
use gateway_types::rot::RotSlot;
1417
use nexus_types::deployment::ExpectedActiveRotSlot;
@@ -21,14 +24,13 @@ use nexus_types::inventory::BaseboardId;
2124
use nexus_types::inventory::CabooseWhich;
2225
use nexus_types::inventory::Collection;
2326
use omicron_common::api::external::TufRepoDescription;
24-
use slog::{debug, error, info, warn};
27+
use slog::{error, info, warn};
2528
use slog_error_chain::InlineErrorChain;
2629
use std::collections::BTreeSet;
2730
use std::sync::Arc;
2831
use thiserror::Error;
2932
use tufaceous_artifact::ArtifactVersion;
3033
use tufaceous_artifact::ArtifactVersionError;
31-
use tufaceous_artifact::KnownArtifactKind;
3234

3335
/// How to handle an MGS-driven update that has become impossible due to
3436
/// unsatisfied preconditions.
@@ -365,39 +367,6 @@ fn mgs_update_status(
365367
}
366368
}
367369

368-
/// Compares a configured SP update with information from inventory and
369-
/// determines the current status of the update. See `MgsUpdateStatus`.
370-
fn mgs_update_status_sp(
371-
desired_version: &ArtifactVersion,
372-
expected_active_version: &ArtifactVersion,
373-
expected_inactive_version: &ExpectedVersion,
374-
found_active_version: &str,
375-
found_inactive_version: Option<&str>,
376-
) -> MgsUpdateStatus {
377-
if found_active_version == desired_version.as_str() {
378-
// If we find the desired version in the active slot, we're done.
379-
return MgsUpdateStatus::Done;
380-
}
381-
382-
// The update hasn't completed.
383-
//
384-
// Check to make sure the contents of the active slot are still what they
385-
// were when we configured this update. If not, then this update cannot
386-
// proceed as currently configured. It will fail its precondition check.
387-
if found_active_version != expected_active_version.as_str() {
388-
return MgsUpdateStatus::Impossible;
389-
}
390-
391-
// Similarly, check the contents of the inactive slot to determine if it
392-
// still matches what we saw when we configured this update. If not, then
393-
// this update cannot proceed as currently configured. It will fail its
394-
// precondition check.
395-
mgs_update_status_inactive_versions(
396-
found_inactive_version,
397-
expected_inactive_version,
398-
)
399-
}
400-
401370
fn mgs_update_status_inactive_versions(
402371
found_inactive_version: Option<&str>,
403372
expected_inactive_version: &ExpectedVersion,
@@ -465,141 +434,6 @@ fn try_make_update(
465434
})
466435
}
467436

468-
/// Determine if the given baseboard needs an SP update and, if so, returns it.
469-
fn try_make_update_sp(
470-
log: &slog::Logger,
471-
baseboard_id: &Arc<BaseboardId>,
472-
inventory: &Collection,
473-
current_artifacts: &TufRepoDescription,
474-
) -> Option<PendingMgsUpdate> {
475-
let Some(sp_info) = inventory.sps.get(baseboard_id) else {
476-
warn!(
477-
log,
478-
"cannot configure SP update for board \
479-
(missing SP info from inventory)";
480-
baseboard_id
481-
);
482-
return None;
483-
};
484-
485-
let Some(active_caboose) =
486-
inventory.caboose_for(CabooseWhich::SpSlot0, baseboard_id)
487-
else {
488-
warn!(
489-
log,
490-
"cannot configure SP update for board \
491-
(missing active caboose from inventory)";
492-
baseboard_id,
493-
);
494-
return None;
495-
};
496-
497-
let Ok(expected_active_version) = active_caboose.caboose.version.parse()
498-
else {
499-
warn!(
500-
log,
501-
"cannot configure SP update for board \
502-
(cannot parse current active version as an ArtifactVersion)";
503-
baseboard_id,
504-
"found_version" => &active_caboose.caboose.version,
505-
);
506-
return None;
507-
};
508-
509-
let board = &active_caboose.caboose.board;
510-
let matching_artifacts: Vec<_> = current_artifacts
511-
.artifacts
512-
.iter()
513-
.filter(|a| {
514-
// A matching SP artifact will have:
515-
//
516-
// - "name" matching the board name (found above from caboose)
517-
// - "kind" matching one of the known SP kinds
518-
519-
if a.id.name != *board {
520-
return false;
521-
}
522-
523-
match a.id.kind.to_known() {
524-
None => false,
525-
Some(
526-
KnownArtifactKind::GimletSp
527-
| KnownArtifactKind::PscSp
528-
| KnownArtifactKind::SwitchSp,
529-
) => true,
530-
Some(
531-
KnownArtifactKind::GimletRot
532-
| KnownArtifactKind::Host
533-
| KnownArtifactKind::Trampoline
534-
| KnownArtifactKind::InstallinatorDocument
535-
| KnownArtifactKind::ControlPlane
536-
| KnownArtifactKind::Zone
537-
| KnownArtifactKind::PscRot
538-
| KnownArtifactKind::SwitchRot
539-
| KnownArtifactKind::GimletRotBootloader
540-
| KnownArtifactKind::PscRotBootloader
541-
| KnownArtifactKind::SwitchRotBootloader,
542-
) => false,
543-
}
544-
})
545-
.collect();
546-
if matching_artifacts.is_empty() {
547-
warn!(
548-
log,
549-
"cannot configure SP update for board (no matching artifact)";
550-
baseboard_id,
551-
);
552-
return None;
553-
}
554-
555-
if matching_artifacts.len() > 1 {
556-
// This should be impossible unless we shipped a TUF repo with multiple
557-
// artifacts for the same board. But it doesn't prevent us from picking
558-
// one and proceeding. Make a note and proceed.
559-
warn!(log, "found more than one matching artifact for SP update");
560-
}
561-
562-
let artifact = matching_artifacts[0];
563-
564-
// If the artifact's version matches what's deployed, then no update is
565-
// needed.
566-
if artifact.id.version == expected_active_version {
567-
debug!(log, "no SP update needed for board"; baseboard_id);
568-
return None;
569-
}
570-
571-
// Begin configuring an update.
572-
let expected_inactive_version = match inventory
573-
.caboose_for(CabooseWhich::SpSlot1, baseboard_id)
574-
.map(|c| c.caboose.version.parse::<ArtifactVersion>())
575-
.transpose()
576-
{
577-
Ok(None) => ExpectedVersion::NoValidVersion,
578-
Ok(Some(v)) => ExpectedVersion::Version(v),
579-
Err(_) => {
580-
warn!(
581-
log,
582-
"cannot configure SP update for board \
583-
(found inactive slot contents but version was not valid)";
584-
baseboard_id
585-
);
586-
return None;
587-
}
588-
};
589-
590-
Some(PendingMgsUpdate {
591-
baseboard_id: baseboard_id.clone(),
592-
sp_type: sp_info.sp_type,
593-
slot_id: sp_info.sp_slot,
594-
details: PendingMgsUpdateDetails::Sp {
595-
expected_active_version,
596-
expected_inactive_version,
597-
},
598-
artifact_hash: artifact.hash,
599-
artifact_version: artifact.id.version.clone(),
600-
})
601-
}
602-
603437
#[cfg(test)]
604438
mod test {
605439
use super::ImpossibleUpdatePolicy;

0 commit comments

Comments
 (0)