Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ensures datasets get propagated into RSS blueprint #7000

Merged
merged 15 commits into from
Nov 12, 2024
Merged
1 change: 1 addition & 0 deletions common/src/disk.rs
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@ impl DatasetName {
&self.pool_name
}

// TODO: Maybe rename this to "kind"?
Copy link
Contributor

Choose a reason for hiding this comment

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

👍 I figure this will have ripple effects which is why you didn't do it in this PR.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Yeah, it's a mechanical change, so I figured I'd punt it out when I get to a less conflict-y place

pub fn dataset(&self) -> &DatasetKind {
&self.kind
}
Expand Down
2 changes: 1 addition & 1 deletion nexus/src/app/rack.rs
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@ impl super::Nexus {
db::model::Dataset::new(
dataset.dataset_id,
dataset.zpool_id,
Some(dataset.request.address),
dataset.request.address,
dataset.request.kind,
)
})
Expand Down
4 changes: 2 additions & 2 deletions nexus/test-utils/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -249,7 +249,7 @@ impl RackInitRequestBuilder {
self.datasets.push(DatasetCreateRequest {
zpool_id: zpool_id.into_untyped_uuid(),
dataset_id,
request: DatasetPutRequest { address, kind },
request: DatasetPutRequest { address: Some(address), kind },
});
let zone = self
.internal_dns_config
Expand All @@ -276,7 +276,7 @@ impl RackInitRequestBuilder {
zpool_id: zpool_id.into_untyped_uuid(),
dataset_id,
request: DatasetPutRequest {
address,
address: Some(address),
kind: DatasetKind::Clickhouse,
},
});
Expand Down
7 changes: 7 additions & 0 deletions nexus/types/src/deployment/zone_type.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ use nexus_sled_agent_shared::inventory::OmicronZoneType;
use nexus_sled_agent_shared::inventory::ZoneKind;
use omicron_common::api::internal::shared::DatasetKind;
use omicron_common::api::internal::shared::NetworkInterface;
use omicron_common::disk::DatasetName;
use schemars::JsonSchema;
use serde::Deserialize;
use serde::Serialize;
Expand Down Expand Up @@ -227,6 +228,12 @@ pub struct DurableDataset<'a> {
pub address: SocketAddrV6,
}

impl<'a> From<DurableDataset<'a>> for DatasetName {
fn from(d: DurableDataset<'a>) -> Self {
DatasetName::new(d.dataset.pool_name.clone(), d.kind)
}
}

impl From<BlueprintZoneType> for OmicronZoneType {
fn from(zone_type: BlueprintZoneType) -> Self {
match zone_type {
Expand Down
2 changes: 1 addition & 1 deletion nexus/types/src/internal_api/params.rs
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ pub struct ZpoolPutRequest {
pub struct DatasetPutRequest {
/// Address on which a service is responding to requests for the
/// dataset.
pub address: SocketAddrV6,
pub address: Option<SocketAddrV6>,

/// Type of dataset being inserted.
pub kind: DatasetKind,
Expand Down
2 changes: 1 addition & 1 deletion openapi/nexus-internal.json
Original file line number Diff line number Diff line change
Expand Up @@ -3128,6 +3128,7 @@
"type": "object",
"properties": {
"address": {
"nullable": true,
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Before this PR: The public-facing API to "add a dataset to the DB" required a SocketAddr type.

This is an artifact which was partially fixed by #2000 - unfortunately, there is code which still uses these IP/port pairs if they exist, but they are not required to exist for a dataset record to be created.

Anyway - TL;DR, they're optional, as they should be.

"description": "Address on which a service is responding to requests for the dataset.",
"type": "string"
},
Expand All @@ -3141,7 +3142,6 @@
}
},
"required": [
"address",
"kind"
]
},
Expand Down
112 changes: 100 additions & 12 deletions sled-agent/src/rack_setup/plan/service.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,9 @@ use omicron_common::backoff::{
retry_notify_ext, retry_policy_internal_service_aggressive, BackoffError,
};
use omicron_common::disk::{
DatasetKind, DatasetName, DatasetsConfig, DiskVariant,
OmicronPhysicalDiskConfig, OmicronPhysicalDisksConfig,
CompressionAlgorithm, DatasetConfig, DatasetKind, DatasetName,
DatasetsConfig, DiskVariant, OmicronPhysicalDiskConfig,
OmicronPhysicalDisksConfig,
};
use omicron_common::ledger::{self, Ledger, Ledgerable};
use omicron_common::policy::{
Expand All @@ -45,7 +46,8 @@ use omicron_common::policy::{
SINGLE_NODE_CLICKHOUSE_REDUNDANCY,
};
use omicron_uuid_kinds::{
ExternalIpUuid, GenericUuid, OmicronZoneUuid, SledUuid, ZpoolUuid,
DatasetUuid, ExternalIpUuid, GenericUuid, OmicronZoneUuid, SledUuid,
ZpoolUuid,
};
use rand::prelude::SliceRandom;
use schemars::JsonSchema;
Expand Down Expand Up @@ -94,6 +96,9 @@ pub enum PlanError {
#[error("Ran out of sleds / U2 storage pools")]
NotEnoughSleds,

#[error("Unexpected dataset kind: {0}")]
UnexpectedDataset(String),

#[error("Found only v1 service plan")]
FoundV1,

Expand All @@ -119,6 +124,54 @@ pub struct SledConfig {
pub zones: Vec<BlueprintZoneConfig>,
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Struggling to comment the right line here -- I'm trying to comment on the pub datasets: DatasetsConfig line above -- but basically:

That's what this PR is most significantly trying to fix

}

impl SledConfig {
/// Adds a zone to the Sled's configuration, as well as any number of
/// durable datasets.
pub fn add_zone_and_datasets(&mut self, zone: BlueprintZoneConfig) {
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

This is RSS's version of "whenever you add a zone, make sure you track all possible datasets used by that zone too".

let fs_dataset_name = DatasetName::new(
zone.filesystem_pool.clone().expect("Missing pool"),
DatasetKind::TransientZone {
name: illumos_utils::zone::zone_name(
zone.zone_type.kind().zone_prefix(),
Some(zone.id),
),
},
);

// Always add a transient filesystem dataset.
let fs_dataset = DatasetConfig {
id: DatasetUuid::new_v4(),
name: fs_dataset_name,
compression: CompressionAlgorithm::Off,
quota: None,
reservation: None,
};
self.datasets.datasets.insert(fs_dataset.id, fs_dataset);

// If a durable dataset exists, add it.
if let Some(dataset) = zone.zone_type.durable_dataset() {
let id = DatasetUuid::new_v4();
self.datasets.datasets.insert(
id,
DatasetConfig {
id,
name: dataset.into(),
compression: CompressionAlgorithm::Off,
quota: None,
reservation: None,
},
);
}

// Add the zone.
//
// Currently this is pushing back to a Vec; we could inspect to
// ensure this function is idempotent, but it currently is not
// re-callable.
self.zones.push(zone);
}
}

#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema)]
pub struct Plan {
pub services: HashMap<SocketAddrV6, SledConfig>,
Expand Down Expand Up @@ -472,6 +525,41 @@ impl Plan {
.iter()
.map(|disk| ZpoolName::new_external(disk.pool_id))
.collect();

// Add all non-discretionary datasets, self-provisioned on the U.2, to the blueprint.
for zpool in &sled_info.u2_zpools {
for intrinsic_dataset in
sled_storage::dataset::U2_EXPECTED_DATASETS
{
let name = intrinsic_dataset.get_name();
let kind = match name {
sled_storage::dataset::ZONE_DATASET => {
DatasetKind::TransientZoneRoot
}
sled_storage::dataset::U2_DEBUG_DATASET => {
DatasetKind::Debug
}
_ => {
return Err(PlanError::UnexpectedDataset(
name.to_string(),
))
}
};

let config = DatasetConfig {
id: DatasetUuid::new_v4(),
name: DatasetName::new(zpool.clone(), kind),
compression: intrinsic_dataset.get_compression(),
quota: intrinsic_dataset.get_quota(),
reservation: None,
};
sled_info
.request
.datasets
.datasets
.insert(config.id, config);
}
}
}

// We'll stripe most services across all available Sleds, round-robin
Expand Down Expand Up @@ -509,7 +597,7 @@ impl Plan {
sled.alloc_dataset_from_u2s(DatasetKind::InternalDns)?;
let filesystem_pool = Some(dataset_name.pool().clone());

sled.request.zones.push(BlueprintZoneConfig {
sled.request.add_zone_and_datasets(BlueprintZoneConfig {
disposition: BlueprintZoneDisposition::InService,
id,
filesystem_pool,
Expand Down Expand Up @@ -544,7 +632,7 @@ impl Plan {
let dataset_name =
sled.alloc_dataset_from_u2s(DatasetKind::Cockroach)?;
let filesystem_pool = Some(dataset_name.pool().clone());
sled.request.zones.push(BlueprintZoneConfig {
sled.request.add_zone_and_datasets(BlueprintZoneConfig {
disposition: BlueprintZoneDisposition::InService,
id,
zone_type: BlueprintZoneType::CockroachDb(
Expand Down Expand Up @@ -592,7 +680,7 @@ impl Plan {
let dataset_name = sled.alloc_dataset_from_u2s(dataset_kind)?;
let filesystem_pool = Some(dataset_name.pool().clone());

sled.request.zones.push(BlueprintZoneConfig {
sled.request.add_zone_and_datasets(BlueprintZoneConfig {
disposition: BlueprintZoneDisposition::InService,
id,
zone_type: BlueprintZoneType::ExternalDns(
Expand Down Expand Up @@ -629,7 +717,7 @@ impl Plan {
.unwrap();
let (nic, external_ip) = svc_port_builder.next_nexus(id)?;
let filesystem_pool = Some(sled.alloc_zpool_from_u2s()?);
sled.request.zones.push(BlueprintZoneConfig {
sled.request.add_zone_and_datasets(BlueprintZoneConfig {
disposition: BlueprintZoneDisposition::InService,
id,
zone_type: BlueprintZoneType::Nexus(
Expand Down Expand Up @@ -673,7 +761,7 @@ impl Plan {
.host_zone_with_one_backend(id, ServiceName::Oximeter, address)
.unwrap();
let filesystem_pool = Some(sled.alloc_zpool_from_u2s()?);
sled.request.zones.push(BlueprintZoneConfig {
sled.request.add_zone_and_datasets(BlueprintZoneConfig {
disposition: BlueprintZoneDisposition::InService,
id,
zone_type: BlueprintZoneType::Oximeter(
Expand Down Expand Up @@ -701,7 +789,7 @@ impl Plan {
let dataset_name =
sled.alloc_dataset_from_u2s(DatasetKind::Clickhouse)?;
let filesystem_pool = Some(dataset_name.pool().clone());
sled.request.zones.push(BlueprintZoneConfig {
sled.request.add_zone_and_datasets(BlueprintZoneConfig {
disposition: BlueprintZoneDisposition::InService,
id,
zone_type: BlueprintZoneType::Clickhouse(
Expand Down Expand Up @@ -736,7 +824,7 @@ impl Plan {
address,
)
.unwrap();
sled.request.zones.push(BlueprintZoneConfig {
sled.request.add_zone_and_datasets(BlueprintZoneConfig {
disposition: BlueprintZoneDisposition::InService,
id,
zone_type: BlueprintZoneType::CruciblePantry(
Expand All @@ -762,7 +850,7 @@ impl Plan {
)
.unwrap();

sled.request.zones.push(BlueprintZoneConfig {
sled.request.add_zone_and_datasets(BlueprintZoneConfig {
disposition: BlueprintZoneDisposition::InService,
id,
zone_type: BlueprintZoneType::Crucible(
Expand Down Expand Up @@ -823,7 +911,7 @@ impl Plan {
.host_zone_with_one_backend(id, svcname, ntp_address)
.unwrap();

sled.request.zones.push(BlueprintZoneConfig {
sled.request.add_zone_and_datasets(BlueprintZoneConfig {
disposition: BlueprintZoneDisposition::InService,
id,
zone_type,
Expand Down
Loading
Loading