Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -26,15 +26,15 @@ blueprint df06bb57-ad42-4431-9206-abff322896c7 created from blueprint af934083-5
> # which does not include any of those blueprints.
> blueprint-history
TIME BLUEPRINT
<REDACTED_TIMESTAMP> 184f10b3-61cb-41ef-9b93-3489b2bac559 starting blueprint with 3 empty sleds
<REDACTED_TIMESTAMP> 184f10b3-61cb-41ef-9b93-3489b2bac559 starting blueprint (empty)
<REDACTED_TIMESTAMP> dbcbd3d6-41ff-48ae-ac0b-1becc9b2fd21



> # You can give it a specific blueprint.
> blueprint-history 8da82a8e-bf97-4fbd-8ddd-9f6462732cf1
TIME BLUEPRINT
<REDACTED_TIMESTAMP> 184f10b3-61cb-41ef-9b93-3489b2bac559 starting blueprint with 3 empty sleds
<REDACTED_TIMESTAMP> 184f10b3-61cb-41ef-9b93-3489b2bac559 starting blueprint (empty)
<REDACTED_TIMESTAMP> dbcbd3d6-41ff-48ae-ac0b-1becc9b2fd21
<REDACTED_TIMESTAMP> 8da82a8e-bf97-4fbd-8ddd-9f6462732cf1

Expand All @@ -43,7 +43,7 @@ TIME BLUEPRINT
> # Running it from the latest blueprint should report all of them.
> blueprint-history latest
TIME BLUEPRINT
<REDACTED_TIMESTAMP> 184f10b3-61cb-41ef-9b93-3489b2bac559 starting blueprint with 3 empty sleds
<REDACTED_TIMESTAMP> 184f10b3-61cb-41ef-9b93-3489b2bac559 starting blueprint (empty)
<REDACTED_TIMESTAMP> dbcbd3d6-41ff-48ae-ac0b-1becc9b2fd21
<REDACTED_TIMESTAMP> 8da82a8e-bf97-4fbd-8ddd-9f6462732cf1
<REDACTED_TIMESTAMP> 58d5e830-0884-47d8-a7cd-b2b3751adeb4
Expand All @@ -64,21 +64,21 @@ TIME BLUEPRINT
> # Show diffs, too.
> blueprint-history --diff latest
TIME BLUEPRINT
<REDACTED_TIMESTAMP> 184f10b3-61cb-41ef-9b93-3489b2bac559 starting blueprint with 3 empty sleds
<REDACTED_TIMESTAMP> 184f10b3-61cb-41ef-9b93-3489b2bac559 starting blueprint (empty)
<REDACTED_TIMESTAMP> dbcbd3d6-41ff-48ae-ac0b-1becc9b2fd21
from: blueprint 184f10b3-61cb-41ef-9b93-3489b2bac559
to: blueprint dbcbd3d6-41ff-48ae-ac0b-1becc9b2fd21

MODIFIED SLEDS:
ADDED SLEDS:

sled 2b8f0cb3-0295-4b3c-bc58-4fe88b57112c (active, config generation 1 -> 2):
sled 2b8f0cb3-0295-4b3c-bc58-4fe88b57112c (active, config generation 2):

host phase 2 contents:
------------------------
slot boot image source
------------------------
A current contents
B current contents
+ A current contents
+ B current contents


physical disks:
Expand Down Expand Up @@ -184,14 +184,14 @@ to: blueprint dbcbd3d6-41ff-48ae-ac0b-1becc9b2fd21
+ nexus 466a9f29-62bf-4e63-924a-b9efdb86afec install dataset in service fd00:1122:3344:102::22


sled 98e6b7c2-2efa-41ca-b20a-0a4d61102fe6 (active, config generation 1 -> 2):
sled 98e6b7c2-2efa-41ca-b20a-0a4d61102fe6 (active, config generation 2):

host phase 2 contents:
------------------------
slot boot image source
------------------------
A current contents
B current contents
+ A current contents
+ B current contents


physical disks:
Expand Down Expand Up @@ -294,14 +294,14 @@ to: blueprint dbcbd3d6-41ff-48ae-ac0b-1becc9b2fd21
+ nexus 0c71b3b2-6ceb-4e8f-b020-b08675e83038 install dataset in service fd00:1122:3344:101::22


sled d81c6a84-79b8-4958-ae41-ea46c9b19763 (active, config generation 1 -> 2):
sled d81c6a84-79b8-4958-ae41-ea46c9b19763 (active, config generation 2):

host phase 2 contents:
------------------------
slot boot image source
------------------------
A current contents
B current contents
+ A current contents
+ B current contents


physical disks:
Expand Down
16 changes: 8 additions & 8 deletions dev-tools/reconfigurator-cli/tests/output/cmds-example-stdout
Original file line number Diff line number Diff line change
Expand Up @@ -694,16 +694,16 @@ external DNS:
from: blueprint 02697f74-b14a-4418-90f0-c28b2a3a6aa9
to: blueprint 86db3308-f817-4626-8838-4085949a6a41

MODIFIED SLEDS:
ADDED SLEDS:
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This isn't that worrisome but I'm not clear on why this happened. This test doesn't appear to explicitly add any sleds.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Above what github shows, these are the current blueprints in the simulated system:

> blueprint-list
T ENA ID                                   PARENT                               TIME_CREATED             
      02697f74-b14a-4418-90f0-c28b2a3a6aa9 <none>                               <REDACTED_TIMESTAMP> 
* yes ade5749d-bdf3-4fab-a8ae-00bea01b3a5a 02697f74-b14a-4418-90f0-c28b2a3a6aa9 <REDACTED_TIMESTAMP> 
      86db3308-f817-4626-8838-4085949a6a41 ade5749d-bdf3-4fab-a8ae-00bea01b3a5a <REDACTED_TIMESTAMP> 

The diff here is between 02697f74-b14a-4418-90f0-c28b2a3a6aa9 and 86db3308-f817-4626-8838-4085949a6a41 (although diffing from 02697f74-b14a-4418-90f0-c28b2a3a6aa9 to ade5749d-bdf3-4fab-a8ae-00bea01b3a5a would show the same behavior). Prior to this change, the initial blueprint 02697f74-b14a-4418-90f0-c28b2a3a6aa9 with was built via build_empty_with_sleds(...), so it had all the sleds present (but they themselves were all empty). On this PR, it's now built via build_empty(), so it has no sleds at all, hence the diff shows the sleds being ADDED instead of MODIFIED. The details within the sled didn't change, because in both cases we're adding all the disks, datasets, and zones.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, I didn't actually answer your question. The test does this:

> load-example --seed test-basic --nsleds 1 --ndisks-per-sled 4

which still creates two blueprints:

> blueprint-list
T ENA ID                                   PARENT                               TIME_CREATED             
      02697f74-b14a-4418-90f0-c28b2a3a6aa9 <none>                               <REDACTED_TIMESTAMP> 
* yes ade5749d-bdf3-4fab-a8ae-00bea01b3a5a 02697f74-b14a-4418-90f0-c28b2a3a6aa9 <REDACTED_TIMESTAMP> 

We used to add the sleds in the first and then flesh out their details in the second; now the first is truly empty, and we add them with their details already fleshed out in the second.


sled 89d02b1b-478c-401a-8e28-7a26f74fa41b (active, config generation 1 -> 2):
sled 89d02b1b-478c-401a-8e28-7a26f74fa41b (active, config generation 2):

host phase 2 contents:
------------------------
slot boot image source
------------------------
A current contents
B current contents
+ A current contents
+ B current contents


physical disks:
Expand Down Expand Up @@ -914,16 +914,16 @@ external DNS:
from: blueprint 86db3308-f817-4626-8838-4085949a6a41
to: blueprint 02697f74-b14a-4418-90f0-c28b2a3a6aa9

MODIFIED SLEDS:
REMOVED SLEDS:

sled 89d02b1b-478c-401a-8e28-7a26f74fa41b (active, config generation 2 -> 1):
sled 89d02b1b-478c-401a-8e28-7a26f74fa41b (was active, config generation 2):

host phase 2 contents:
------------------------
slot boot image source
------------------------
A current contents
B current contents
- A current contents
- B current contents


physical disks:
Expand Down
157 changes: 37 additions & 120 deletions nexus/db-queries/src/db/datastore/deployment.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3146,20 +3146,16 @@ mod tests {
use nexus_types::deployment::BlueprintHostPhase2DesiredContents;
use nexus_types::deployment::BlueprintHostPhase2DesiredSlots;
use nexus_types::deployment::BlueprintPhysicalDiskDisposition;
use nexus_types::deployment::BlueprintZoneConfig;
use nexus_types::deployment::BlueprintZoneDisposition;
use nexus_types::deployment::BlueprintZoneImageSource;
use nexus_types::deployment::BlueprintZoneType;
use nexus_types::deployment::ExpectedActiveRotSlot;
use nexus_types::deployment::OmicronZoneExternalFloatingIp;
use nexus_types::deployment::PendingMgsUpdate;
use nexus_types::deployment::PlanningInput;
use nexus_types::deployment::PlanningInputBuilder;
use nexus_types::deployment::SledDetails;
use nexus_types::deployment::SledDisk;
use nexus_types::deployment::SledFilter;
use nexus_types::deployment::SledResources;
use nexus_types::deployment::blueprint_zone_type;
use nexus_types::external_api::views::PhysicalDiskPolicy;
use nexus_types::external_api::views::PhysicalDiskState;
use nexus_types::external_api::views::SledPolicy;
Expand All @@ -3168,36 +3164,24 @@ mod tests {
use nexus_types::inventory::Collection;
use omicron_common::address::IpRange;
use omicron_common::address::Ipv6Subnet;
use omicron_common::api::external::MacAddr;
use omicron_common::api::external::Name;
use omicron_common::api::external::TufArtifactMeta;
use omicron_common::api::external::TufRepoDescription;
use omicron_common::api::external::TufRepoMeta;
use omicron_common::api::external::Vni;
use omicron_common::api::internal::shared::NetworkInterface;
use omicron_common::api::internal::shared::NetworkInterfaceKind;
use omicron_common::disk::DiskIdentity;
use omicron_common::disk::M2Slot;
use omicron_common::update::ArtifactId;
use omicron_common::zpool_name::ZpoolName;
use omicron_test_utils::dev;
use omicron_test_utils::dev::poll::CondCheckError;
use omicron_test_utils::dev::poll::wait_for_condition;
use omicron_uuid_kinds::ExternalIpUuid;
use omicron_uuid_kinds::OmicronZoneUuid;
use omicron_uuid_kinds::PhysicalDiskUuid;
use omicron_uuid_kinds::SledUuid;
use omicron_uuid_kinds::ZpoolUuid;
use oxnet::IpNet;
use pretty_assertions::assert_eq;
use rand::Rng;
use std::collections::BTreeSet;
use std::mem;
use std::net::IpAddr;
use std::net::Ipv4Addr;
use std::net::Ipv6Addr;
use std::net::SocketAddrV6;
use std::str::FromStr;
use std::sync::Arc;
use std::sync::LazyLock;
use std::sync::atomic::AtomicBool;
Expand Down Expand Up @@ -3311,10 +3295,7 @@ mod tests {
let (opctx, datastore) = (db.opctx(), db.datastore());

// Create an empty blueprint from it
let blueprint1 = BlueprintBuilder::build_empty_with_sleds(
std::iter::empty(),
"test",
);
let blueprint1 = BlueprintBuilder::build_empty("test");
let authz_blueprint = authz_blueprint_from_id(blueprint1.id);

// Trying to read it from the database should fail with the relevant
Expand Down Expand Up @@ -4039,10 +4020,7 @@ mod tests {
// Create three blueprints:
// * `blueprint1` has no parent
// * `blueprint2` and `blueprint3` both have `blueprint1` as parent
let blueprint1 = BlueprintBuilder::build_empty_with_sleds(
std::iter::empty(),
"test1",
);
let blueprint1 = BlueprintBuilder::build_empty("test1");
let blueprint2 = BlueprintBuilder::new_based_on(
&logctx.log,
&blueprint1,
Expand Down Expand Up @@ -4190,10 +4168,7 @@ mod tests {
let (opctx, datastore) = (db.opctx(), db.datastore());

// Create an initial blueprint and a child.
let blueprint1 = BlueprintBuilder::build_empty_with_sleds(
std::iter::empty(),
"test1",
);
let blueprint1 = BlueprintBuilder::build_empty("test1");
let blueprint2 = BlueprintBuilder::new_based_on(
&logctx.log,
&blueprint1,
Expand Down Expand Up @@ -4292,104 +4267,46 @@ mod tests {
logctx.cleanup_successful();
}

async fn create_blueprint_with_external_ip(
datastore: &DataStore,
opctx: &OpContext,
) -> Blueprint {
// Create an initial blueprint and a child.
let sled_id = SledUuid::new_v4();
let mut blueprint = BlueprintBuilder::build_empty_with_sleds(
[sled_id].into_iter(),
"test1",
);

// To observe realistic database behavior, we need the invocation of
// "blueprint_ensure_external_networking_resources" to actually write something
// back to the database.
//
// While this is *mostly* made-up blueprint contents, the part that matters
// is that it's provisioning a zone (Nexus) which does have resources
// to be allocated.
let ip_range = IpRange::try_from((
Ipv4Addr::new(10, 0, 0, 1),
Ipv4Addr::new(10, 0, 0, 10),
))
.unwrap();
let (service_authz_ip_pool, service_ip_pool) = datastore
.ip_pools_service_lookup(&opctx, IpVersion::V4)
.await
.expect("lookup service ip pool");
datastore
.ip_pool_add_range(
&opctx,
&service_authz_ip_pool,
&service_ip_pool,
&ip_range,
)
.await
.expect("add range to service ip pool");
let zone_id = OmicronZoneUuid::new_v4();
blueprint
.sleds
.get_mut(&sled_id)
.unwrap()
.zones
.insert_unique(BlueprintZoneConfig {
disposition: BlueprintZoneDisposition::InService,
id: zone_id,
filesystem_pool: ZpoolName::new_external(ZpoolUuid::new_v4()),
zone_type: BlueprintZoneType::Nexus(
blueprint_zone_type::Nexus {
internal_address: SocketAddrV6::new(
Ipv6Addr::LOCALHOST,
0,
0,
0,
),
lockstep_port: 0,
external_ip: OmicronZoneExternalFloatingIp {
id: ExternalIpUuid::new_v4(),
ip: "10.0.0.1".parse().unwrap(),
},
nic: NetworkInterface {
id: Uuid::new_v4(),
kind: NetworkInterfaceKind::Service {
id: *zone_id.as_untyped_uuid(),
},
name: Name::from_str("mynic").unwrap(),
ip: "172.30.2.6".parse().unwrap(),
mac: MacAddr::random_system(),
subnet: IpNet::host_net(IpAddr::V6(
Ipv6Addr::LOCALHOST,
)),
vni: Vni::random(),
primary: true,
slot: 1,
transit_ips: vec![],
},
external_tls: false,
external_dns_servers: vec![],
nexus_generation: Generation::new(),
},
),
image_source: BlueprintZoneImageSource::InstallDataset,
})
.expect("freshly generated zone IDs are unique");

blueprint
}

#[tokio::test]
async fn test_ensure_external_networking_works_with_good_target() {
const TEST_NAME: &str =
"test_ensure_external_networking_works_with_good_target";
// Setup
let logctx = dev::test_setup_log(
"test_ensure_external_networking_works_with_good_target",
);
let logctx = dev::test_setup_log(TEST_NAME);
let db = TestDatabase::new_with_datastore(&logctx.log).await;
let (opctx, datastore) = (db.opctx(), db.datastore());

let blueprint =
create_blueprint_with_external_ip(&datastore, &opctx).await;
let (example, mut blueprint) =
ExampleSystemBuilder::new(&opctx.log, TEST_NAME).build();

// Insert the IP pool ranges used by our example system.
for pool_range in
example.system.external_ip_policy().clone().into_raw_ranges()
{
// This looks up the pool again for each range; we only need at most
// two (one V4, one V6), but our example system doesn't have many
// ranges so this should be fine.
let (service_authz_ip_pool, service_ip_pool) = datastore
.ip_pools_service_lookup(&opctx, pool_range.version().into())
.await
.expect("lookup service ip pool");
datastore
.ip_pool_add_range(
&opctx,
&service_authz_ip_pool,
&service_ip_pool,
&pool_range,
)
.await
.expect("add range to service IP pool");
}

// `ExampleSystemBuilder` returns a blueprint that has an empty parent.
// To make `blueprint` the target, we have to either insert that parent
// and make it the target first, or modify `blueprint` to make it look
// like it's the original. The latter is shorter.
blueprint.parent_blueprint_id = None;

datastore.blueprint_insert(&opctx, &blueprint).await.unwrap();

let bp_target = BlueprintTarget {
Expand Down
Loading
Loading