Skip to content
Closed
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
30 changes: 20 additions & 10 deletions openapi/sled-agent.json
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@
},
"/filesystem": {
"put": {
"operationId": "filesystem_put",
"operationId": "filesystems_put",
"requestBody": {
"content": {
"application/json": {
Expand Down Expand Up @@ -608,14 +608,29 @@
]
},
"DatasetEnsureBody": {
"description": "Used to request that the Sled initialize multiple datasets.",
"type": "object",
"properties": {
"datasets": {
"type": "array",
"items": {
"$ref": "#/components/schemas/DatasetEnsureRequest"
}
}
},
"required": [
"datasets"
]
},
"DatasetEnsureRequest": {
"description": "Used to request a new dataset kind exists within a zpool.\n\nMany dataset types are associated with services that will be instantiated when the dataset is detected.",
"type": "object",
"properties": {
"address": {
"type": "string"
},
"dataset_kind": {
"$ref": "#/components/schemas/DatasetKind"
"dataset_name": {
"$ref": "#/components/schemas/DatasetName"
},
"gz_address": {
"nullable": true,
Expand All @@ -626,17 +641,12 @@
"id": {
"type": "string",
"format": "uuid"
},
"zpool_id": {
"type": "string",
"format": "uuid"
}
},
"required": [
"address",
"dataset_kind",
"id",
"zpool_id"
"dataset_name",
"id"
]
},
"DatasetKind": {
Expand Down
14 changes: 3 additions & 11 deletions sled-agent/src/http_entrypoints.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ type SledApiDescription = ApiDescription<SledAgent>;
pub fn api() -> SledApiDescription {
fn register_endpoints(api: &mut SledApiDescription) -> Result<(), String> {
api.register(disk_put)?;
api.register(filesystem_put)?;
api.register(filesystems_put)?;
api.register(instance_issue_disk_snapshot_request)?;
api.register(instance_put_migration_ids)?;
api.register(instance_put_state)?;
Expand Down Expand Up @@ -113,21 +113,13 @@ async fn sled_role_get(
method = PUT,
path = "/filesystem",
}]
async fn filesystem_put(
async fn filesystems_put(
rqctx: RequestContext<SledAgent>,
body: TypedBody<DatasetEnsureBody>,
) -> Result<HttpResponseUpdatedNoContent, HttpError> {
let sa = rqctx.context();
let body_args = body.into_inner();
sa.filesystem_ensure(
body_args.id,
body_args.zpool_id,
body_args.dataset_kind,
body_args.address,
body_args.gz_address,
)
.await
.map_err(|e| Error::from(e))?;
sa.filesystems_ensure(body_args).await.map_err(|e| Error::from(e))?;
Ok(HttpResponseUpdatedNoContent())
}

Expand Down
23 changes: 14 additions & 9 deletions sled-agent/src/params.rs
Original file line number Diff line number Diff line change
Expand Up @@ -313,18 +313,22 @@ impl std::fmt::Display for DatasetKind {
}
}

/// Used to request that the Sled initialize multiple datasets.
#[derive(Clone, Debug, Deserialize, Serialize, JsonSchema, PartialEq)]
pub struct DatasetEnsureBody {
pub datasets: Vec<DatasetEnsureRequest>,
}

/// Used to request a new dataset kind exists within a zpool.
///
/// Many dataset types are associated with services that will be
/// instantiated when the dataset is detected.
#[derive(Clone, Debug, Deserialize, Serialize, JsonSchema, PartialEq)]
pub struct DatasetEnsureBody {
pub struct DatasetEnsureRequest {
// The UUID of the dataset, as well as the service using it directly.
pub id: Uuid,
// The name (and UUID) of the Zpool which we are inserting into.
pub zpool_id: Uuid,
// The type of the filesystem.
pub dataset_kind: DatasetKind,
pub dataset_name: crate::storage::dataset::DatasetName,
// The address on which the zone will listen for requests.
pub address: SocketAddrV6,
// The addresses in the global zone which should be created, if necessary
Expand All @@ -333,14 +337,15 @@ pub struct DatasetEnsureBody {
pub gz_address: Option<Ipv6Addr>,
}

impl From<DatasetEnsureBody> for sled_agent_client::types::DatasetEnsureBody {
fn from(p: DatasetEnsureBody) -> Self {
impl From<DatasetEnsureRequest>
for sled_agent_client::types::DatasetEnsureRequest
{
fn from(p: DatasetEnsureRequest) -> Self {
Self {
zpool_id: p.zpool_id,
dataset_kind: p.dataset_kind.into(),
id: p.id,
dataset_name: p.dataset_name.into(),
address: p.address.to_string(),
gz_address: p.gz_address,
id: p.id,
}
}
}
Expand Down
70 changes: 40 additions & 30 deletions sled-agent/src/rack_setup/plan/service.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,15 @@
use crate::bootstrap::params::StartSledAgentRequest;
use crate::ledger::{Ledger, Ledgerable};
use crate::params::{
DatasetEnsureBody, ServiceType, ServiceZoneRequest, ServiceZoneService,
DatasetEnsureRequest, ServiceType, ServiceZoneRequest, ServiceZoneService,
ZoneType,
};
use crate::rack_setup::config::SetupServiceConfig as Config;
use crate::storage::dataset::DatasetName;
use crate::storage_manager::StorageResources;
use camino::Utf8PathBuf;
use dns_service_client::types::DnsConfigParams;
use illumos_utils::zpool::ZpoolName;
use internal_dns::{ServiceName, DNS_ZONE};
use omicron_common::address::{
get_sled_address, get_switch_zone_address, Ipv6Subnet, ReservedRackSubnet,
Expand Down Expand Up @@ -93,7 +95,7 @@ pub enum PlanError {
pub struct SledRequest {
/// Datasets to be created.
#[serde(default, rename = "dataset")]
pub datasets: Vec<DatasetEnsureBody>,
pub datasets: Vec<DatasetEnsureRequest>,

/// Services to be instantiated.
#[serde(default, rename = "service")]
Expand Down Expand Up @@ -165,7 +167,7 @@ impl Plan {
async fn get_u2_zpools_from_sled(
log: &Logger,
address: SocketAddrV6,
) -> Result<Vec<Uuid>, PlanError> {
) -> Result<Vec<ZpoolName>, PlanError> {
let dur = std::time::Duration::from_secs(60);
let client = reqwest::ClientBuilder::new()
.connect_timeout(dur)
Expand All @@ -179,15 +181,17 @@ impl Plan {
);

let get_u2_zpools = || async {
let zpools: Vec<Uuid> = client
let zpools: Vec<ZpoolName> = client
.zpools_get()
.await
.map(|response| {
response
.into_inner()
.into_iter()
.filter_map(|zpool| match zpool.disk_type {
SledAgentTypes::DiskType::U2 => Some(zpool.id),
SledAgentTypes::DiskType::U2 => {
Some(ZpoolName::new_external(zpool.id))
}
SledAgentTypes::DiskType::M2 => None,
})
.collect()
Expand Down Expand Up @@ -304,24 +308,20 @@ impl Plan {
dns_address,
nic: nic.clone(),
};
let dataset_name =
DatasetName::new(u2_zpools[0].clone(), dataset_kind);

request.datasets.push(DatasetEnsureBody {
request.datasets.push(DatasetEnsureRequest {
id,
zpool_id: u2_zpools[0],
dataset_kind: dataset_kind.clone(),
dataset_name: dataset_name.clone(),
address: http_address,
gz_address: None,
});
request.services.push(ServiceZoneRequest {
id,
zone_type: ZoneType::ExternalDns,
addresses: vec![internal_ip],
dataset: Some(crate::storage::dataset::DatasetName::new(
illumos_utils::zpool::ZpoolName::new_external(
u2_zpools[0],
),
dataset_kind,
)),
dataset: Some(dataset_name),
gz_addresses: vec![],
services: vec![ServiceZoneService {
id,
Expand Down Expand Up @@ -411,10 +411,12 @@ impl Plan {
dns_builder
.service_backend_zone(ServiceName::Cockroach, &zone, port)
.unwrap();
request.datasets.push(DatasetEnsureBody {
request.datasets.push(DatasetEnsureRequest {
id,
zpool_id: u2_zpools[0],
dataset_kind: crate::params::DatasetKind::CockroachDb,
dataset_name: DatasetName::new(
u2_zpools[0].clone(),
crate::params::DatasetKind::CockroachDb,
),
address,
gz_address: None,
});
Expand All @@ -430,10 +432,12 @@ impl Plan {
dns_builder
.service_backend_zone(ServiceName::Clickhouse, &zone, port)
.unwrap();
request.datasets.push(DatasetEnsureBody {
request.datasets.push(DatasetEnsureRequest {
id,
zpool_id: u2_zpools[0],
dataset_kind: crate::params::DatasetKind::Clickhouse,
dataset_name: DatasetName::new(
u2_zpools[0].clone(),
crate::params::DatasetKind::Clickhouse,
),
address,
gz_address: None,
});
Expand All @@ -442,7 +446,7 @@ impl Plan {
// Each zpool gets a crucible zone.
//
// TODO(https://github.com/oxidecomputer/omicron/issues/732): Remove
for zpool_id in &u2_zpools {
for pool in &u2_zpools {
let ip = addr_alloc.next().expect("Not enough addrs");
let port = omicron_common::address::CRUCIBLE_PORT;
let address = SocketAddrV6::new(ip, port, 0, 0);
Expand All @@ -456,10 +460,12 @@ impl Plan {
)
.unwrap();

request.datasets.push(DatasetEnsureBody {
request.datasets.push(DatasetEnsureRequest {
id,
zpool_id: *zpool_id,
dataset_kind: crate::params::DatasetKind::Crucible,
dataset_name: DatasetName::new(
pool.clone(),
crate::params::DatasetKind::Crucible,
),
address,
gz_address: None,
});
Expand All @@ -475,20 +481,24 @@ impl Plan {
SocketAddrV6::new(dns_ip, DNS_HTTP_PORT, 0, 0);
let id = Uuid::new_v4();
let zone = dns_builder.host_zone(id, dns_ip).unwrap();
let dataset_name = DatasetName::new(
u2_zpools[0].clone(),
crate::params::DatasetKind::InternalDns {
http_address,
dns_address,
},
);

dns_builder
.service_backend_zone(
ServiceName::InternalDns,
&zone,
DNS_HTTP_PORT,
)
.unwrap();
request.datasets.push(DatasetEnsureBody {
request.datasets.push(DatasetEnsureRequest {
id,
zpool_id: u2_zpools[0],
dataset_kind: crate::params::DatasetKind::InternalDns {
http_address,
dns_address,
},
dataset_name,
address: http_address,
gz_address: Some(dns_subnet.gz_address().ip()),
});
Expand Down
Loading