Skip to content

Commit a22f72e

Browse files
committed
Use measurements with sprockets
1 parent bc19d8f commit a22f72e

File tree

15 files changed

+302
-58
lines changed

15 files changed

+302
-58
lines changed

Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

sled-agent/src/artifact_store.rs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ use sled_agent_config_reconciler::ConfigReconcilerHandle;
4141
use sled_agent_config_reconciler::InternalDisksReceiver;
4242
use sled_agent_types::artifact::ArtifactConfig;
4343
use sled_agent_types::artifact::{ArtifactListResponse, ArtifactPutResponse};
44+
use sled_agent_config_reconciler::SledAgentArtifactStore;
4445
use slog::{Logger, error, info};
4546
use slog_error_chain::{InlineErrorChain, SlogInlineError};
4647
use tokio::fs::File;
@@ -54,6 +55,22 @@ use tufaceous_artifact::ArtifactHash;
5455
const LEDGER_PATH: &str = "artifact-config.json";
5556
const TEMP_SUBDIR: &str = "tmp";
5657

58+
// Workaround wrapper for orphan rules.
59+
#[derive(Clone)]
60+
pub(crate) struct SledAgentArtifactStoreWrapper(
61+
pub Arc<ArtifactStore<InternalDisksReceiver>>,
62+
);
63+
64+
impl SledAgentArtifactStore for SledAgentArtifactStoreWrapper {
65+
async fn get_artifact(
66+
&self,
67+
artifact: ArtifactHash,
68+
) -> anyhow::Result<tokio::fs::File> {
69+
let file = self.0.get(artifact).await?;
70+
Ok(file)
71+
}
72+
}
73+
5774
/// Content-addressable local storage for software artifacts.
5875
///
5976
/// If you need to read a file managed by the artifact store from somewhere else

sled-agent/src/bootstrap/client.rs

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ use super::params::version;
1010
use super::views::SledAgentResponse;
1111
use crate::bootstrap::views::Response;
1212
use crate::bootstrap::views::ResponseEnvelope;
13+
use sled_agent_config_reconciler::MeasurementsReceiver;
1314
use sled_agent_types::sled::StartSledAgentRequest;
1415
use slog::Logger;
1516
use slog_error_chain::SlogInlineError;
@@ -77,15 +78,17 @@ pub(crate) struct Client {
7778
addr: SocketAddrV6,
7879
log: Logger,
7980
sprockets_conf: SprocketsConfig,
81+
measurements_rx: MeasurementsReceiver,
8082
}
8183

8284
impl Client {
8385
pub(crate) fn new(
8486
addr: SocketAddrV6,
8587
sprockets_conf: SprocketsConfig,
88+
measurements_rx: MeasurementsReceiver,
8689
log: Logger,
8790
) -> Self {
88-
Self { addr, sprockets_conf, log }
91+
Self { addr, sprockets_conf, log, measurements_rx }
8992
}
9093

9194
/// Start sled agent by sending an initialization request determined from
@@ -117,8 +120,14 @@ impl Client {
117120
// Establish connection and sprockets connection (if possible).
118121
// The sprockets client loads the associated root certificates at this point.
119122
//
120-
// TODO: Use a real corpus
121-
let corpus = vec![];
123+
let corpus = self.measurements_rx.latest_measurements();
124+
if corpus.is_empty() {
125+
error!(self.log, "The measurement log shouldn't be empty");
126+
}
127+
for c in &corpus {
128+
info!(self.log, "Using file {c} in corpus");
129+
}
130+
122131
let stream = SprocketsClient::connect(
123132
self.sprockets_conf.clone(),
124133
self.addr,

sled-agent/src/bootstrap/http_entrypoints.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ use omicron_common::api::external::Error;
2424
use omicron_uuid_kinds::RackInitUuid;
2525
use omicron_uuid_kinds::RackResetUuid;
2626
use sled_agent_config_reconciler::InternalDisksReceiver;
27+
use sled_agent_config_reconciler::MeasurementsReceiver;
2728
use sled_agent_types::rack_init::{
2829
RackInitializeRequest, RackInitializeRequestParams,
2930
};
@@ -48,6 +49,7 @@ pub(crate) struct BootstrapServerContext {
4849
mpsc::Sender<oneshot::Sender<Result<(), BootstrapError>>>,
4950
pub(crate) sprockets: SprocketsConfig,
5051
pub(crate) trust_quorum_handle: trust_quorum::NodeTaskHandle,
52+
pub(crate) measurements_rx: MeasurementsReceiver,
5153
}
5254

5355
impl BootstrapServerContext {
@@ -60,6 +62,7 @@ impl BootstrapServerContext {
6062
self.sprockets.clone(),
6163
self.global_zone_bootstrap_ip,
6264
&self.internal_disks_rx,
65+
&self.measurements_rx,
6366
&self.bootstore_node_handle,
6467
&self.trust_quorum_handle,
6568
request,
@@ -132,6 +135,7 @@ impl BootstrapAgentApi for BootstrapAgentImpl {
132135
.start_reset(
133136
&ctx.base_log,
134137
ctx.sprockets.clone(),
138+
ctx.measurements_rx.clone(),
135139
ctx.global_zone_bootstrap_ip,
136140
)
137141
.map_err(|err| HttpError::for_bad_request(None, err.to_string()))?;

sled-agent/src/bootstrap/rack_ops.rs

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ use bootstore::schemes::v0 as bootstore;
1010
use omicron_uuid_kinds::RackInitUuid;
1111
use omicron_uuid_kinds::RackResetUuid;
1212
use sled_agent_config_reconciler::InternalDisksReceiver;
13+
use sled_agent_config_reconciler::MeasurementsReceiver;
1314
use sled_agent_types::rack_init::RackInitializeRequestParams;
1415
use sled_agent_types::rack_ops::{RackOperationStatus, RssStep};
1516
use slog::Logger;
@@ -149,6 +150,7 @@ impl RssAccess {
149150
sprockets: SprocketsConfig,
150151
global_zone_bootstrap_ip: Ipv6Addr,
151152
internal_disks_rx: &InternalDisksReceiver,
153+
measurements_rx: &MeasurementsReceiver,
152154
bootstore_node_handle: &bootstore::NodeHandle,
153155
trust_quorum_handle: &trust_quorum::NodeTaskHandle,
154156
request: RackInitializeRequestParams,
@@ -188,6 +190,7 @@ impl RssAccess {
188190
mem::drop(status);
189191
let parent_log = parent_log.clone();
190192
let internal_disks_rx = internal_disks_rx.clone();
193+
let measurements_rx = measurements_rx.clone();
191194
let bootstore_node_handle = bootstore_node_handle.clone();
192195
let status = Arc::clone(&self.status);
193196
let trust_quorum_handle = trust_quorum_handle.clone();
@@ -197,6 +200,7 @@ impl RssAccess {
197200
sprockets,
198201
global_zone_bootstrap_ip,
199202
internal_disks_rx,
203+
measurements_rx,
200204
bootstore_node_handle,
201205
trust_quorum_handle,
202206
request,
@@ -224,6 +228,7 @@ impl RssAccess {
224228
&self,
225229
parent_log: &Logger,
226230
sprockets: SprocketsConfig,
231+
measurements_rx: MeasurementsReceiver,
227232
global_zone_bootstrap_ip: Ipv6Addr,
228233
) -> Result<RackResetUuid, RssAccessError> {
229234
let mut status = self.status.lock().unwrap();
@@ -264,6 +269,7 @@ impl RssAccess {
264269
let result = rack_reset(
265270
&parent_log,
266271
sprockets,
272+
measurements_rx,
267273
global_zone_bootstrap_ip,
268274
)
269275
.await;
@@ -339,6 +345,7 @@ async fn rack_initialize(
339345
sprockets: SprocketsConfig,
340346
global_zone_bootstrap_ip: Ipv6Addr,
341347
internal_disks_rx: InternalDisksReceiver,
348+
measurements_rx: MeasurementsReceiver,
342349
bootstore_node_handle: bootstore::NodeHandle,
343350
trust_quorum_handle: trust_quorum::NodeTaskHandle,
344351
request: RackInitializeRequestParams,
@@ -350,6 +357,7 @@ async fn rack_initialize(
350357
request,
351358
global_zone_bootstrap_ip,
352359
internal_disks_rx,
360+
measurements_rx,
353361
bootstore_node_handle,
354362
trust_quorum_handle,
355363
step_tx,
@@ -360,8 +368,14 @@ async fn rack_initialize(
360368
async fn rack_reset(
361369
parent_log: &Logger,
362370
sprockets: SprocketsConfig,
371+
measurements_rx: MeasurementsReceiver,
363372
global_zone_bootstrap_ip: Ipv6Addr,
364373
) -> Result<(), SetupServiceError> {
365-
RssHandle::run_rss_reset(parent_log, global_zone_bootstrap_ip, sprockets)
366-
.await
374+
RssHandle::run_rss_reset(
375+
parent_log,
376+
global_zone_bootstrap_ip,
377+
sprockets,
378+
measurements_rx,
379+
)
380+
.await
367381
}

sled-agent/src/bootstrap/rss_handle.rs

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ use omicron_common::backoff::BackoffError;
1515
use omicron_common::backoff::retry_notify;
1616
use omicron_common::backoff::retry_policy_local;
1717
use sled_agent_config_reconciler::InternalDisksReceiver;
18+
use sled_agent_config_reconciler::MeasurementsReceiver;
1819
use sled_agent_types::rack_init::RackInitializeRequestParams;
1920
use sled_agent_types::rack_ops::RssStep;
2021
use sled_agent_types::sled::StartSledAgentRequest;
@@ -52,11 +53,16 @@ impl RssHandle {
5253
config: RackInitializeRequestParams,
5354
our_bootstrap_address: Ipv6Addr,
5455
internal_disks_rx: InternalDisksReceiver,
56+
measurements_rx: MeasurementsReceiver,
5557
bootstore: bootstore::NodeHandle,
5658
trust_quorum: trust_quorum::NodeTaskHandle,
5759
step_tx: watch::Sender<RssStep>,
5860
) -> Result<(), SetupServiceError> {
59-
let (tx, rx) = rss_channel(our_bootstrap_address, sprockets);
61+
let (tx, rx) = rss_channel(
62+
our_bootstrap_address,
63+
sprockets,
64+
measurements_rx.clone(),
65+
);
6066

6167
let rss = RackSetupService::new(
6268
log.new(o!("component" => "RSS")),
@@ -77,8 +83,13 @@ impl RssHandle {
7783
log: &Logger,
7884
our_bootstrap_address: Ipv6Addr,
7985
sprockets: SprocketsConfig,
86+
measurements_rx: MeasurementsReceiver,
8087
) -> Result<(), SetupServiceError> {
81-
let (tx, rx) = rss_channel(our_bootstrap_address, sprockets);
88+
let (tx, rx) = rss_channel(
89+
our_bootstrap_address,
90+
sprockets,
91+
measurements_rx.clone(),
92+
);
8293

8394
let rss = RackSetupService::new_reset_rack(
8495
log.new(o!("component" => "RSS")),
@@ -95,11 +106,13 @@ async fn initialize_sled_agent(
95106
log: &Logger,
96107
bootstrap_addr: SocketAddrV6,
97108
sprockets: SprocketsConfig,
109+
measurements_rx: MeasurementsReceiver,
98110
request: &StartSledAgentRequest,
99111
) -> Result<(), bootstrap_agent_client::Error> {
100112
let client = bootstrap_agent_client::Client::new(
101113
bootstrap_addr,
102114
sprockets,
115+
measurements_rx,
103116
log.new(o!("BootstrapAgentClient" => bootstrap_addr.to_string())),
104117
);
105118

@@ -131,11 +144,12 @@ async fn initialize_sled_agent(
131144
fn rss_channel(
132145
our_bootstrap_address: Ipv6Addr,
133146
sprockets: SprocketsConfig,
147+
measurements_rx: MeasurementsReceiver,
134148
) -> (BootstrapAgentHandle, BootstrapAgentHandleReceiver) {
135149
let (tx, rx) = mpsc::channel(32);
136150
(
137151
BootstrapAgentHandle { inner: tx, our_bootstrap_address },
138-
BootstrapAgentHandleReceiver { inner: rx, sprockets },
152+
BootstrapAgentHandleReceiver { inner: rx, sprockets, measurements_rx },
139153
)
140154
}
141155

@@ -207,6 +221,7 @@ impl BootstrapAgentHandle {
207221
struct BootstrapAgentHandleReceiver {
208222
inner: mpsc::Receiver<Request>,
209223
sprockets: SprocketsConfig,
224+
measurements_rx: MeasurementsReceiver,
210225
}
211226

212227
impl BootstrapAgentHandleReceiver {
@@ -227,10 +242,12 @@ impl BootstrapAgentHandleReceiver {
227242
// of the initialization requests, allowing them to run concurrently.
228243

229244
let s = self.sprockets.clone();
245+
let mx = self.measurements_rx.clone();
230246
let mut futs = requests
231247
.into_iter()
232248
.map(|(bootstrap_addr, request)| {
233249
let value = s.clone();
250+
let measurements_rx = mx.clone();
234251
async move {
235252
info!(
236253
log, "Received initialization request from RSS";
@@ -242,6 +259,7 @@ impl BootstrapAgentHandleReceiver {
242259
log,
243260
bootstrap_addr,
244261
value,
262+
measurements_rx,
245263
&request,
246264
)
247265
.await

sled-agent/src/bootstrap/server.rs

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -204,6 +204,60 @@ impl Server {
204204
// enqueue another, and we can send back an HTTP busy.
205205
let (sled_reset_tx, sled_reset_rx) = mpsc::channel(1);
206206

207+
while let Err(
208+
sled_agent_config_reconciler::InventoryError::WaitingOnLedger,
209+
) =
210+
long_running_task_handles.config_reconciler.ledgered_sled_config()
211+
{
212+
// waiting for our ledger to run...
213+
}
214+
215+
// Get our pre-boot measurements, first we check the ledger
216+
let pre_boot = match long_running_task_handles
217+
.config_reconciler
218+
.ledgered_sled_config()
219+
{
220+
// Lie down. Try not to cry. Cry a lot.
221+
Err(_) => {
222+
vec![]
223+
}
224+
// We haven't run RSS, we'll take what we get from the measurement manifest
225+
Ok(None) => match long_running_task_handles
226+
.zone_image_resolver
227+
.status()
228+
.to_inventory()
229+
.measurement_manifest
230+
.boot_inventory
231+
{
232+
Err(_) => {
233+
vec![]
234+
}
235+
Ok(s) => s
236+
.artifacts
237+
.iter()
238+
.filter_map(|entry| match entry.status {
239+
Ok(_) => Some(entry.path.clone()),
240+
Err(_) => None,
241+
})
242+
.collect(),
243+
},
244+
// Do an early resolution
245+
Ok(Some(s)) => {
246+
long_running_task_handles
247+
.config_reconciler
248+
.bootstrap_measurement_reconciler(
249+
&long_running_task_handles.zone_image_resolver.status(),
250+
&long_running_task_handles
251+
.config_reconciler
252+
.internal_disks_rx()
253+
.current(),
254+
&s.measurements,
255+
&base_log,
256+
)
257+
.await
258+
}
259+
};
260+
207261
// Start the bootstrap dropshot server.
208262
let bootstrap_context = BootstrapServerContext {
209263
base_log: base_log.clone(),
@@ -216,13 +270,24 @@ impl Server {
216270
sled_reset_tx,
217271
sprockets: config.sprockets.clone(),
218272
trust_quorum_handle: long_running_task_handles.trust_quorum.clone(),
273+
measurements_rx: long_running_task_handles
274+
.config_reconciler
275+
.measurement_corpus_rx(pre_boot.clone())
276+
.await
277+
.clone(),
219278
};
220279
let bootstrap_http_server = start_dropshot_server(bootstrap_context)?;
221280

222281
// Create a channel for proxying sled-initialization requests that land
223282
// in the sprockets server to our bootstrap agent `Inner` task.
224283
let (sled_init_tx, sled_init_rx) = mpsc::channel(1);
225284

285+
let measurements = long_running_task_handles
286+
.config_reconciler
287+
.measurement_corpus_rx(pre_boot)
288+
.await
289+
.clone();
290+
226291
// We don't bother to wrap this bind in a
227292
// `wait_while_handling_hardware_updates()` because (a) binding should
228293
// be fast and (b) can succeed regardless of any pending hardware
@@ -235,6 +300,7 @@ impl Server {
235300
0,
236301
),
237302
sled_init_tx,
303+
measurements,
238304
config.sprockets.clone(),
239305
&base_log,
240306
)

0 commit comments

Comments
 (0)