@@ -2443,14 +2443,26 @@ fn cmd_blueprint_diff(
2443
2443
// each blueprint. To do that we need to construct a list of sleds suitable
2444
2444
// for the executor.
2445
2445
let sleds_by_id = make_sleds_by_id ( state. system ( ) . description ( ) ) ?;
2446
+
2447
+ // It's tricky to figure out which active Nexus generation number to use
2448
+ // when diff'ing blueprints. What's currently active might be wholly
2449
+ // different from what's here. (Imagine generation 7 is active and these
2450
+ // blueprints are from Nexus generation 4.) What's most likely useful is
2451
+ // picking the Nexus generation of the blueprint itself.
2452
+ let blueprint1_active_nexus_generation =
2453
+ blueprint_active_nexus_generation ( & blueprint1) ;
2454
+ let blueprint2_active_nexus_generation =
2455
+ blueprint_active_nexus_generation ( & blueprint2) ;
2446
2456
let internal_dns_config1 = blueprint_internal_dns_config (
2447
2457
& blueprint1,
2448
2458
& sleds_by_id,
2459
+ blueprint1_active_nexus_generation,
2449
2460
& Default :: default ( ) ,
2450
2461
) ?;
2451
2462
let internal_dns_config2 = blueprint_internal_dns_config (
2452
2463
& blueprint2,
2453
2464
& sleds_by_id,
2465
+ blueprint2_active_nexus_generation,
2454
2466
& Default :: default ( ) ,
2455
2467
) ?;
2456
2468
let dns_diff = DnsDiff :: new ( & internal_dns_config1, & internal_dns_config2)
@@ -2462,11 +2474,13 @@ fn cmd_blueprint_diff(
2462
2474
& blueprint1,
2463
2475
state. config ( ) . silo_names ( ) ,
2464
2476
external_dns_zone_name. to_owned ( ) ,
2477
+ blueprint1_active_nexus_generation,
2465
2478
) ;
2466
2479
let external_dns_config2 = blueprint_external_dns_config (
2467
2480
& blueprint2,
2468
2481
state. config ( ) . silo_names ( ) ,
2469
2482
external_dns_zone_name. to_owned ( ) ,
2483
+ blueprint2_active_nexus_generation,
2470
2484
) ;
2471
2485
let dns_diff = DnsDiff :: new ( & external_dns_config1, & external_dns_config2)
2472
2486
. context ( "failed to assemble external DNS diff" ) ?;
@@ -2524,19 +2538,23 @@ fn cmd_blueprint_diff_dns(
2524
2538
}
2525
2539
} ;
2526
2540
2541
+ let blueprint_active_generation =
2542
+ blueprint_active_nexus_generation ( & blueprint) ;
2527
2543
let blueprint_dns_zone = match dns_group {
2528
2544
CliDnsGroup :: Internal => {
2529
2545
let sleds_by_id = make_sleds_by_id ( state. system ( ) . description ( ) ) ?;
2530
2546
blueprint_internal_dns_config (
2531
2547
blueprint,
2532
2548
& sleds_by_id,
2549
+ blueprint_active_generation,
2533
2550
& Default :: default ( ) ,
2534
2551
) ?
2535
2552
}
2536
2553
CliDnsGroup :: External => blueprint_external_dns_config (
2537
2554
blueprint,
2538
2555
state. config ( ) . silo_names ( ) ,
2539
2556
state. config ( ) . external_dns_zone_name ( ) . to_owned ( ) ,
2557
+ blueprint_active_generation,
2540
2558
) ,
2541
2559
} ;
2542
2560
@@ -3005,9 +3023,12 @@ fn cmd_load_example(
3005
3023
3006
3024
// Generate the internal and external DNS configs based on the blueprint.
3007
3025
let sleds_by_id = make_sleds_by_id ( & example. system ) ?;
3026
+ let blueprint_nexus_generation =
3027
+ blueprint_active_nexus_generation ( & blueprint) ;
3008
3028
let internal_dns = blueprint_internal_dns_config (
3009
3029
& blueprint,
3010
3030
& sleds_by_id,
3031
+ blueprint_nexus_generation,
3011
3032
& Default :: default ( ) ,
3012
3033
) ?;
3013
3034
let external_dns_zone_name =
@@ -3016,6 +3037,7 @@ fn cmd_load_example(
3016
3037
& blueprint,
3017
3038
state. config_mut ( ) . silo_names ( ) ,
3018
3039
external_dns_zone_name,
3040
+ blueprint_nexus_generation,
3019
3041
) ;
3020
3042
3021
3043
let blueprint_id = blueprint. id ;
@@ -3082,3 +3104,30 @@ fn cmd_file_contents(args: FileContentsArgs) -> anyhow::Result<Option<String>> {
3082
3104
3083
3105
Ok ( Some ( s) )
3084
3106
}
3107
+
3108
+ /// Returns the "active Nexus generation" to use for a historical blueprint
3109
+ /// (i.e., a blueprint that may not have been generated or executed against the
3110
+ /// current simulated state). This is used for `blueprint-diff`, for example,
3111
+ /// which avoids assuming anything about the simulated state in comparing the
3112
+ /// two blueprints.
3113
+ ///
3114
+ /// In general, the active Nexus generation for a blueprint is not well-defined.
3115
+ /// We cannot know what the active Nexus generation was at some point in the
3116
+ /// past. But we do know that it's one of these two values:
3117
+ ///
3118
+ /// - `blueprint.nexus_generation - 1`, if this blueprint was created as part
3119
+ /// of an upgrade, starting with the point where the Nexus handoff was
3120
+ /// initiated (inclusive) and ending with the first blueprint after the
3121
+ /// handoff (exclusive). In most cases, this means that this is the single
3122
+ /// blueprint during an upgrade that triggered the handoff.
3123
+ /// - `blueprint.nexus_generation` otherwise (which includes all other
3124
+ /// blueprints that are created during an upgrade and all blueprints created
3125
+ /// outside of an upgrade).
3126
+ ///
3127
+ /// This implementation always returns `blueprint.nexus_generation`. In the
3128
+ /// second case above, this is always correct. In the first case, this is
3129
+ /// basically equivalent to assuming that the Nexus handoff had happened
3130
+ /// instantaneously when the blueprint was created.
3131
+ fn blueprint_active_nexus_generation ( blueprint : & Blueprint ) -> Generation {
3132
+ blueprint. nexus_generation
3133
+ }
0 commit comments