5
5
//! Facilities for making choices about MGS-managed updates
6
6
7
7
mod rot;
8
+ mod sp;
8
9
9
10
use crate :: mgs_updates:: rot:: RotUpdateState ;
10
11
use crate :: mgs_updates:: rot:: mgs_update_status_rot;
11
12
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;
12
15
13
16
use gateway_types:: rot:: RotSlot ;
14
17
use nexus_types:: deployment:: ExpectedActiveRotSlot ;
@@ -21,14 +24,13 @@ use nexus_types::inventory::BaseboardId;
21
24
use nexus_types:: inventory:: CabooseWhich ;
22
25
use nexus_types:: inventory:: Collection ;
23
26
use omicron_common:: api:: external:: TufRepoDescription ;
24
- use slog:: { debug , error, info, warn} ;
27
+ use slog:: { error, info, warn} ;
25
28
use slog_error_chain:: InlineErrorChain ;
26
29
use std:: collections:: BTreeSet ;
27
30
use std:: sync:: Arc ;
28
31
use thiserror:: Error ;
29
32
use tufaceous_artifact:: ArtifactVersion ;
30
33
use tufaceous_artifact:: ArtifactVersionError ;
31
- use tufaceous_artifact:: KnownArtifactKind ;
32
34
33
35
/// How to handle an MGS-driven update that has become impossible due to
34
36
/// unsatisfied preconditions.
@@ -365,39 +367,6 @@ fn mgs_update_status(
365
367
}
366
368
}
367
369
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
-
401
370
fn mgs_update_status_inactive_versions (
402
371
found_inactive_version : Option < & str > ,
403
372
expected_inactive_version : & ExpectedVersion ,
@@ -465,141 +434,6 @@ fn try_make_update(
465
434
} )
466
435
}
467
436
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
-
603
437
#[ cfg( test) ]
604
438
mod test {
605
439
use super :: ImpossibleUpdatePolicy ;
0 commit comments