Skip to content

Add logic for mupdate override/artifacts for measurements#9870

Merged
labbott merged 3 commits intomainfrom
labbott/measurement_mupdate_override
Feb 27, 2026
Merged

Add logic for mupdate override/artifacts for measurements#9870
labbott merged 3 commits intomainfrom
labbott/measurement_mupdate_override

Conversation

@labbott
Copy link
Contributor

@labbott labbott commented Feb 17, 2026

No description provided.

@labbott labbott force-pushed the labbott/measurement_mupdate_override branch from 64b420f to 0a2346a Compare February 17, 2026 17:36
{
let potential_path = dataset.join(m.hash.to_string());

// This could technically be a TOCTOU issue but arguably all the paths we
Copy link
Contributor

Choose a reason for hiding this comment

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

Are artifacts distributed as a part of the TUF repo artifact replication? If so, I don't think this function is right - we should be asking the artifact store to read files on our behalf, not going underneath it directly to the dataset. Although now that I'm writing this, I see we don't do that for zones. That doesn't seem right to me, but maybe it's okay? (cc @sunshowers / @iliana who maybe discussed this before?)

We do go through the artifact store for host OS images:

let artifact =
artifact_store.get_artifact(desired).await.map_err(|err| {
BootPartitionError::MissingDesiredArtifact { desired, err }
})?;

Either way, we'll also need to update the cross-checks between the config reconciler and the artifact store to avoid both directions of error: the artifact store removing measurements we need or us ledgering a config that references a measurement that hasn't yet been replicated to the store:

// Helper to return all the `ArtifactHash`es contained in a config.
fn config_artifact_hashes(
config: &OmicronSledConfig,
) -> impl Iterator<Item = ArtifactHash> + '_ {
config
.zones
.iter()
.filter_map(|zone| zone.image_source.artifact_hash())
.chain(config.host_phase_2.slot_a.artifact_hash())
.chain(config.host_phase_2.slot_b.artifact_hash())
}

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yeah I definitely based this logic off of the zones. I'll give this a look.

Copy link
Contributor

Choose a reason for hiding this comment

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

For zones I think it makes sense to read the zone images directly out of the artifact store. (The path is directly provided to zoneadm, iirc.) But if we're copying these files then I think we ought to use the similar flow as the host phase 2 image where we use get_artifact and do an io::copy into whatever file we're writing to.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

we're not copying the files. the paths are getting passed down to sprockets which will eventually just read the file into memory.

Copy link
Contributor

Choose a reason for hiding this comment

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

OK. Then I think going underneath the artifact store to get the path is fine, and arguably I should add a method that just gives you a path to an artifact and clean up the zone side of things too.

@labbott labbott force-pushed the labbott/measurement_mupdate_override branch from 0a2346a to ffd6043 Compare February 25, 2026 20:49
@labbott labbott merged commit 7c56d21 into main Feb 27, 2026
16 checks passed
@labbott labbott deleted the labbott/measurement_mupdate_override branch February 27, 2026 12:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants