Skip to content

Commit

Permalink
Allow multiple RoT versions in the same repository (#6586)
Browse files Browse the repository at this point in the history
  • Loading branch information
labbott authored Sep 25, 2024
1 parent dbbb77b commit c394189
Show file tree
Hide file tree
Showing 24 changed files with 1,125 additions and 371 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions gateway-types/src/caboose.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,6 @@ pub struct SpComponentCaboose {
pub board: String,
pub name: String,
pub version: String,
pub sign: Option<String>,
pub epoch: Option<String>,
}
41 changes: 39 additions & 2 deletions gateway/src/http_entrypoints.rs
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,8 @@ impl GatewayApi for GatewayImpl {
const CABOOSE_KEY_BOARD: [u8; 4] = *b"BORD";
const CABOOSE_KEY_NAME: [u8; 4] = *b"NAME";
const CABOOSE_KEY_VERSION: [u8; 4] = *b"VERS";
const CABOOSE_KEY_SIGN: [u8; 4] = *b"SIGN";
const CABOOSE_KEY_EPOC: [u8; 4] = *b"EPOC";

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

let caboose =
SpComponentCaboose { git_commit, board, name, version };
// Not all images include the SIGN or EPOC in the caboose, if it's not present
// don't treat it as an error

let sign = match sp
.read_component_caboose(
component,
firmware_slot,
CABOOSE_KEY_SIGN,
)
.await
.ok()
{
None => None,
Some(v) => Some(from_utf8(&CABOOSE_KEY_SIGN, v)?),
};

let epoch = match sp
.read_component_caboose(
component,
firmware_slot,
CABOOSE_KEY_EPOC,
)
.await
.ok()
{
None => None,
Some(v) => Some(from_utf8(&CABOOSE_KEY_EPOC, v)?),
};

let caboose = SpComponentCaboose {
git_commit,
board,
name,
version,
sign,
epoch,
};

Ok(HttpResponseOk(caboose))
};
Expand Down
4 changes: 4 additions & 0 deletions nexus/inventory/src/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1087,6 +1087,8 @@ mod test {
git_commit: String::from("git_commit1"),
name: String::from("name1"),
version: String::from("version1"),
sign: None,
epoch: None,
};
assert!(!builder
.found_caboose_already(&bogus_baseboard, CabooseWhich::SpSlot0));
Expand Down Expand Up @@ -1153,6 +1155,8 @@ mod test {
git_commit: String::from("git_commit2"),
name: String::from("name2"),
version: String::from("version2"),
sign: None,
epoch: None,
},
)
.unwrap_err();
Expand Down
2 changes: 2 additions & 0 deletions nexus/inventory/src/examples.rs
Original file line number Diff line number Diff line change
Expand Up @@ -512,6 +512,8 @@ pub fn caboose(unique: &str) -> SpComponentCaboose {
git_commit: format!("git_commit_{}", unique),
name: format!("name_{}", unique),
version: format!("version_{}", unique),
sign: None,
epoch: None,
}
}

Expand Down
8 changes: 8 additions & 0 deletions openapi/gateway.json
Original file line number Diff line number Diff line change
Expand Up @@ -2603,12 +2603,20 @@
"board": {
"type": "string"
},
"epoch": {
"nullable": true,
"type": "string"
},
"git_commit": {
"type": "string"
},
"name": {
"type": "string"
},
"sign": {
"nullable": true,
"type": "string"
},
"version": {
"type": "string"
}
Expand Down
19 changes: 18 additions & 1 deletion openapi/wicketd.json
Original file line number Diff line number Diff line change
Expand Up @@ -1661,6 +1661,15 @@
"items": {
"$ref": "#/components/schemas/ArtifactHashId"
}
},
"sign": {
"nullable": true,
"type": "array",
"items": {
"type": "integer",
"format": "uint8",
"minimum": 0
}
}
},
"required": [
Expand Down Expand Up @@ -3413,18 +3422,26 @@
]
},
"SpComponentCaboose": {
"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>",
"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>",
"type": "object",
"properties": {
"board": {
"type": "string"
},
"epoch": {
"nullable": true,
"type": "string"
},
"git_commit": {
"type": "string"
},
"name": {
"type": "string"
},
"sign": {
"nullable": true,
"type": "string"
},
"version": {
"type": "string"
}
Expand Down
4 changes: 4 additions & 0 deletions sp-sim/src/gimlet.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1351,12 +1351,16 @@ impl SpHandler for Handler {
(SpComponent::ROT, b"NAME", _, _) => ROT_NAME,
(SpComponent::ROT, b"VERS", 0, _) => ROT_VERS0,
(SpComponent::ROT, b"VERS", 1, _) => ROT_VERS1,
// gimlet staging/devel hash
(SpComponent::ROT, b"SIGN", _, _) => &"11594bb5548a757e918e6fe056e2ad9e084297c9555417a025d8788eacf55daf".as_bytes(),
(SpComponent::STAGE0, b"GITC", 0, false) => STAGE0_GITC0,
(SpComponent::STAGE0, b"GITC", 1, false) => STAGE0_GITC1,
(SpComponent::STAGE0, b"BORD", _, false) => STAGE0_BORD,
(SpComponent::STAGE0, b"NAME", _, false) => STAGE0_NAME,
(SpComponent::STAGE0, b"VERS", 0, false) => STAGE0_VERS0,
(SpComponent::STAGE0, b"VERS", 1, false) => STAGE0_VERS1,
// gimlet staging/devel hash
(SpComponent::STAGE0, b"SIGN", _, false) => &"11594bb5548a757e918e6fe056e2ad9e084297c9555417a025d8788eacf55daf".as_bytes(),
_ => return Err(SpError::NoSuchCabooseKey(key)),
};

Expand Down
4 changes: 4 additions & 0 deletions sp-sim/src/sidecar.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1061,12 +1061,16 @@ impl SpHandler for Handler {
(SpComponent::ROT, b"NAME", _, _) => ROT_NAME,
(SpComponent::ROT, b"VERS", 0, _) => ROT_VERS0,
(SpComponent::ROT, b"VERS", 1, _) => ROT_VERS1,
// sidecar staging/devel hash
(SpComponent::ROT, b"SIGN", _, _) => &"1432cc4cfe5688c51b55546fe37837c753cfbc89e8c3c6aabcf977fdf0c41e27".as_bytes(),
(SpComponent::STAGE0, b"GITC", 0, false) => STAGE0_GITC0,
(SpComponent::STAGE0, b"GITC", 1, false) => STAGE0_GITC1,
(SpComponent::STAGE0, b"BORD", _, false) => STAGE0_BORD,
(SpComponent::STAGE0, b"NAME", _, false) => STAGE0_NAME,
(SpComponent::STAGE0, b"VERS", 0, false) => STAGE0_VERS0,
(SpComponent::STAGE0, b"VERS", 1, false) => STAGE0_VERS1,
// sidecar staging/devel hash
(SpComponent::STAGE0, b"SIGN", _, false) => &"1432cc4cfe5688c51b55546fe37837c753cfbc89e8c3c6aabcf977fdf0c41e27".as_bytes(),
_ => return Err(SpError::NoSuchCabooseKey(key)),
};

Expand Down
3 changes: 3 additions & 0 deletions tufaceous-lib/src/assemble/manifest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -297,11 +297,14 @@ impl<'a> FakeDataAttributes<'a> {
KnownArtifactKind::SwitchRot => "SimRot",
};

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

let mut builder = HubrisArchiveBuilder::with_fake_image();
Expand Down
25 changes: 22 additions & 3 deletions update-common/src/artifacts/artifacts_with_plan.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,10 @@ pub struct ArtifactsWithPlan {
// will contain two entries mapping each of the images to their data.
by_hash: DebugIgnore<HashMap<ArtifactHashId, ExtractedArtifactDataHandle>>,

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

// Ensure we know how to apply updates from this set of artifacts; we'll
// remember the plan we create.
let UpdatePlanBuildOutput { plan, by_id, by_hash, artifacts_meta } =
builder.build()?;
let UpdatePlanBuildOutput {
plan,
by_id,
by_hash,
rot_by_sign,
artifacts_meta,
} = builder.build()?;

let tuf_repository = repository.repo();

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

Ok(Self { description, by_id, by_hash: by_hash.into(), plan })
Ok(Self {
description,
by_id,
by_hash: by_hash.into(),
rot_by_sign: rot_by_sign.into(),
plan,
})
}

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

pub fn rot_by_sign(&self) -> &HashMap<ArtifactId, Vec<u8>> {
&self.rot_by_sign
}

pub fn get_by_hash(
&self,
id: &ArtifactHashId,
Expand Down
Loading

0 comments on commit c394189

Please sign in to comment.