Skip to content

Commit c394189

Browse files
authored
Allow multiple RoT versions in the same repository (#6586)
1 parent dbbb77b commit c394189

File tree

24 files changed

+1125
-371
lines changed

24 files changed

+1125
-371
lines changed

Cargo.lock

+1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

gateway-types/src/caboose.rs

+2
Original file line numberDiff line numberDiff line change
@@ -12,4 +12,6 @@ pub struct SpComponentCaboose {
1212
pub board: String,
1313
pub name: String,
1414
pub version: String,
15+
pub sign: Option<String>,
16+
pub epoch: Option<String>,
1517
}

gateway/src/http_entrypoints.rs

+39-2
Original file line numberDiff line numberDiff line change
@@ -217,6 +217,8 @@ impl GatewayApi for GatewayImpl {
217217
const CABOOSE_KEY_BOARD: [u8; 4] = *b"BORD";
218218
const CABOOSE_KEY_NAME: [u8; 4] = *b"NAME";
219219
const CABOOSE_KEY_VERSION: [u8; 4] = *b"VERS";
220+
const CABOOSE_KEY_SIGN: [u8; 4] = *b"SIGN";
221+
const CABOOSE_KEY_EPOC: [u8; 4] = *b"EPOC";
220222

221223
let apictx = rqctx.context();
222224
let PathSpComponent { sp, component } = path.into_inner();
@@ -287,8 +289,43 @@ impl GatewayApi for GatewayImpl {
287289
let name = from_utf8(&CABOOSE_KEY_NAME, name)?;
288290
let version = from_utf8(&CABOOSE_KEY_VERSION, version)?;
289291

290-
let caboose =
291-
SpComponentCaboose { git_commit, board, name, version };
292+
// Not all images include the SIGN or EPOC in the caboose, if it's not present
293+
// don't treat it as an error
294+
295+
let sign = match sp
296+
.read_component_caboose(
297+
component,
298+
firmware_slot,
299+
CABOOSE_KEY_SIGN,
300+
)
301+
.await
302+
.ok()
303+
{
304+
None => None,
305+
Some(v) => Some(from_utf8(&CABOOSE_KEY_SIGN, v)?),
306+
};
307+
308+
let epoch = match sp
309+
.read_component_caboose(
310+
component,
311+
firmware_slot,
312+
CABOOSE_KEY_EPOC,
313+
)
314+
.await
315+
.ok()
316+
{
317+
None => None,
318+
Some(v) => Some(from_utf8(&CABOOSE_KEY_EPOC, v)?),
319+
};
320+
321+
let caboose = SpComponentCaboose {
322+
git_commit,
323+
board,
324+
name,
325+
version,
326+
sign,
327+
epoch,
328+
};
292329

293330
Ok(HttpResponseOk(caboose))
294331
};

nexus/inventory/src/builder.rs

+4
Original file line numberDiff line numberDiff line change
@@ -1087,6 +1087,8 @@ mod test {
10871087
git_commit: String::from("git_commit1"),
10881088
name: String::from("name1"),
10891089
version: String::from("version1"),
1090+
sign: None,
1091+
epoch: None,
10901092
};
10911093
assert!(!builder
10921094
.found_caboose_already(&bogus_baseboard, CabooseWhich::SpSlot0));
@@ -1153,6 +1155,8 @@ mod test {
11531155
git_commit: String::from("git_commit2"),
11541156
name: String::from("name2"),
11551157
version: String::from("version2"),
1158+
sign: None,
1159+
epoch: None,
11561160
},
11571161
)
11581162
.unwrap_err();

nexus/inventory/src/examples.rs

+2
Original file line numberDiff line numberDiff line change
@@ -512,6 +512,8 @@ pub fn caboose(unique: &str) -> SpComponentCaboose {
512512
git_commit: format!("git_commit_{}", unique),
513513
name: format!("name_{}", unique),
514514
version: format!("version_{}", unique),
515+
sign: None,
516+
epoch: None,
515517
}
516518
}
517519

openapi/gateway.json

+8
Original file line numberDiff line numberDiff line change
@@ -2603,12 +2603,20 @@
26032603
"board": {
26042604
"type": "string"
26052605
},
2606+
"epoch": {
2607+
"nullable": true,
2608+
"type": "string"
2609+
},
26062610
"git_commit": {
26072611
"type": "string"
26082612
},
26092613
"name": {
26102614
"type": "string"
26112615
},
2616+
"sign": {
2617+
"nullable": true,
2618+
"type": "string"
2619+
},
26122620
"version": {
26132621
"type": "string"
26142622
}

openapi/wicketd.json

+18-1
Original file line numberDiff line numberDiff line change
@@ -1661,6 +1661,15 @@
16611661
"items": {
16621662
"$ref": "#/components/schemas/ArtifactHashId"
16631663
}
1664+
},
1665+
"sign": {
1666+
"nullable": true,
1667+
"type": "array",
1668+
"items": {
1669+
"type": "integer",
1670+
"format": "uint8",
1671+
"minimum": 0
1672+
}
16641673
}
16651674
},
16661675
"required": [
@@ -3413,18 +3422,26 @@
34133422
]
34143423
},
34153424
"SpComponentCaboose": {
3416-
"description": "SpComponentCaboose\n\n<details><summary>JSON schema</summary>\n\n```json { \"type\": \"object\", \"required\": [ \"board\", \"git_commit\", \"name\", \"version\" ], \"properties\": { \"board\": { \"type\": \"string\" }, \"git_commit\": { \"type\": \"string\" }, \"name\": { \"type\": \"string\" }, \"version\": { \"type\": \"string\" } } } ``` </details>",
3425+
"description": "SpComponentCaboose\n\n<details><summary>JSON schema</summary>\n\n```json { \"type\": \"object\", \"required\": [ \"board\", \"git_commit\", \"name\", \"version\" ], \"properties\": { \"board\": { \"type\": \"string\" }, \"epoch\": { \"type\": [ \"string\", \"null\" ] }, \"git_commit\": { \"type\": \"string\" }, \"name\": { \"type\": \"string\" }, \"sign\": { \"type\": [ \"string\", \"null\" ] }, \"version\": { \"type\": \"string\" } } } ``` </details>",
34173426
"type": "object",
34183427
"properties": {
34193428
"board": {
34203429
"type": "string"
34213430
},
3431+
"epoch": {
3432+
"nullable": true,
3433+
"type": "string"
3434+
},
34223435
"git_commit": {
34233436
"type": "string"
34243437
},
34253438
"name": {
34263439
"type": "string"
34273440
},
3441+
"sign": {
3442+
"nullable": true,
3443+
"type": "string"
3444+
},
34283445
"version": {
34293446
"type": "string"
34303447
}

sp-sim/src/gimlet.rs

+4
Original file line numberDiff line numberDiff line change
@@ -1351,12 +1351,16 @@ impl SpHandler for Handler {
13511351
(SpComponent::ROT, b"NAME", _, _) => ROT_NAME,
13521352
(SpComponent::ROT, b"VERS", 0, _) => ROT_VERS0,
13531353
(SpComponent::ROT, b"VERS", 1, _) => ROT_VERS1,
1354+
// gimlet staging/devel hash
1355+
(SpComponent::ROT, b"SIGN", _, _) => &"11594bb5548a757e918e6fe056e2ad9e084297c9555417a025d8788eacf55daf".as_bytes(),
13541356
(SpComponent::STAGE0, b"GITC", 0, false) => STAGE0_GITC0,
13551357
(SpComponent::STAGE0, b"GITC", 1, false) => STAGE0_GITC1,
13561358
(SpComponent::STAGE0, b"BORD", _, false) => STAGE0_BORD,
13571359
(SpComponent::STAGE0, b"NAME", _, false) => STAGE0_NAME,
13581360
(SpComponent::STAGE0, b"VERS", 0, false) => STAGE0_VERS0,
13591361
(SpComponent::STAGE0, b"VERS", 1, false) => STAGE0_VERS1,
1362+
// gimlet staging/devel hash
1363+
(SpComponent::STAGE0, b"SIGN", _, false) => &"11594bb5548a757e918e6fe056e2ad9e084297c9555417a025d8788eacf55daf".as_bytes(),
13601364
_ => return Err(SpError::NoSuchCabooseKey(key)),
13611365
};
13621366

sp-sim/src/sidecar.rs

+4
Original file line numberDiff line numberDiff line change
@@ -1061,12 +1061,16 @@ impl SpHandler for Handler {
10611061
(SpComponent::ROT, b"NAME", _, _) => ROT_NAME,
10621062
(SpComponent::ROT, b"VERS", 0, _) => ROT_VERS0,
10631063
(SpComponent::ROT, b"VERS", 1, _) => ROT_VERS1,
1064+
// sidecar staging/devel hash
1065+
(SpComponent::ROT, b"SIGN", _, _) => &"1432cc4cfe5688c51b55546fe37837c753cfbc89e8c3c6aabcf977fdf0c41e27".as_bytes(),
10641066
(SpComponent::STAGE0, b"GITC", 0, false) => STAGE0_GITC0,
10651067
(SpComponent::STAGE0, b"GITC", 1, false) => STAGE0_GITC1,
10661068
(SpComponent::STAGE0, b"BORD", _, false) => STAGE0_BORD,
10671069
(SpComponent::STAGE0, b"NAME", _, false) => STAGE0_NAME,
10681070
(SpComponent::STAGE0, b"VERS", 0, false) => STAGE0_VERS0,
10691071
(SpComponent::STAGE0, b"VERS", 1, false) => STAGE0_VERS1,
1072+
// sidecar staging/devel hash
1073+
(SpComponent::STAGE0, b"SIGN", _, false) => &"1432cc4cfe5688c51b55546fe37837c753cfbc89e8c3c6aabcf977fdf0c41e27".as_bytes(),
10701074
_ => return Err(SpError::NoSuchCabooseKey(key)),
10711075
};
10721076

tufaceous-lib/src/assemble/manifest.rs

+3
Original file line numberDiff line numberDiff line change
@@ -297,11 +297,14 @@ impl<'a> FakeDataAttributes<'a> {
297297
KnownArtifactKind::SwitchRot => "SimRot",
298298
};
299299

300+
// For our purposes sign = board represents what we want for the RoT
301+
// and we don't care about the SP at this point
300302
let caboose = CabooseBuilder::default()
301303
.git_commit("this-is-fake-data")
302304
.board(board)
303305
.version(self.version.to_string())
304306
.name(self.name)
307+
.sign(board)
305308
.build();
306309

307310
let mut builder = HubrisArchiveBuilder::with_fake_image();

update-common/src/artifacts/artifacts_with_plan.rs

+22-3
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,10 @@ pub struct ArtifactsWithPlan {
5858
// will contain two entries mapping each of the images to their data.
5959
by_hash: DebugIgnore<HashMap<ArtifactHashId, ExtractedArtifactDataHandle>>,
6060

61+
// Map from Rot artifact IDs to hash of signing information. This is
62+
// used to select between different artifact versions in the same
63+
// repository
64+
rot_by_sign: DebugIgnore<HashMap<ArtifactId, Vec<u8>>>,
6165
// The plan to use to update a component within the rack.
6266
plan: UpdatePlan,
6367
}
@@ -240,8 +244,13 @@ impl ArtifactsWithPlan {
240244

241245
// Ensure we know how to apply updates from this set of artifacts; we'll
242246
// remember the plan we create.
243-
let UpdatePlanBuildOutput { plan, by_id, by_hash, artifacts_meta } =
244-
builder.build()?;
247+
let UpdatePlanBuildOutput {
248+
plan,
249+
by_id,
250+
by_hash,
251+
rot_by_sign,
252+
artifacts_meta,
253+
} = builder.build()?;
245254

246255
let tuf_repository = repository.repo();
247256

@@ -266,7 +275,13 @@ impl ArtifactsWithPlan {
266275
let description =
267276
TufRepoDescription { repo: repo_meta, artifacts: artifacts_meta };
268277

269-
Ok(Self { description, by_id, by_hash: by_hash.into(), plan })
278+
Ok(Self {
279+
description,
280+
by_id,
281+
by_hash: by_hash.into(),
282+
rot_by_sign: rot_by_sign.into(),
283+
plan,
284+
})
270285
}
271286

272287
/// Returns the `ArtifactsDocument` corresponding to this TUF repo.
@@ -289,6 +304,10 @@ impl ArtifactsWithPlan {
289304
&self.plan
290305
}
291306

307+
pub fn rot_by_sign(&self) -> &HashMap<ArtifactId, Vec<u8>> {
308+
&self.rot_by_sign
309+
}
310+
292311
pub fn get_by_hash(
293312
&self,
294313
id: &ArtifactHashId,

0 commit comments

Comments
 (0)