Skip to content

check the layer media type before flashing#9

Open
bennyz wants to merge 1 commit intojumpstarter-dev:mainfrom
bennyz:fix-layer-selection
Open

check the layer media type before flashing#9
bennyz wants to merge 1 commit intojumpstarter-dev:mainfrom
bennyz:fix-layer-selection

Conversation

@bennyz
Copy link
Member

@bennyz bennyz commented Mar 18, 2026

To avoid flashing non disk layers we need to check the media type

To avoid flashing non disk layers we need to check the media type

Signed-off-by: Benny Zlotnik <bzlotnik@redhat.com>
Assisted-by: claude-sonnet-4.6
@coderabbitai
Copy link

coderabbitai bot commented Mar 18, 2026

📝 Walkthrough

Walkthrough

Modified the get_single_layer method in ImageManifest to implement a new layer selection strategy. Added an artifact_type field to support matching layers by media type, with fallback logic to prioritize automotive disk image formats.

Changes

Cohort / File(s) Summary
Layer Selection Logic
src/fls/oci/manifest.rs
Added artifact_type: Option<String> field to ImageManifest. Reworked get_single_layer to enforce no-layer errors, handle single-layer cases directly, match layers by artifact_type, and fall back to automotive disk image media types before returning errors.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Poem

🐰 A manifest now knows its type,
With layers picked with careful gripe,
Disk images aligned just right,
Selection logic shining bright!
hops with glee

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title 'check the layer media type before flashing' accurately summarizes the main change—adding media type checking logic to select the correct layer before flashing.
Description check ✅ Passed The description 'To avoid flashing non disk layers we need to check the media type' is directly related to the changeset, which adds artifact_type field and reworks layer selection logic based on media types.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
📝 Coding Plan
  • Generate coding plan for human review comments

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (1)
src/fls/oci/manifest.rs (1)

67-69: Add direct tests for the new selection rules.

A couple of focused unit tests for (1) artifact_type selection, (2) single non-disk layer rejection, and (3) the no-match error would cover the new branches in get_single_layer(). The current tests in this file only exercise parsing.

Also applies to: 149-168

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/fls/oci/manifest.rs` around lines 67 - 69, Add three focused unit tests
for Manifest::get_single_layer covering the new selection branches: (1) create a
manifest with artifact_type set and layers such that the correct layer is chosen
then assert get_single_layer returns that layer, (2) create a manifest with a
single layer whose mediaType is not a disk type and assert get_single_layer
returns the expected rejection/error, and (3) create a manifest with no matching
layers and assert get_single_layer returns the no-match error. Locate the
Manifest struct and the get_single_layer method to construct test Manifests and
expected Layer descriptors, use the same error types returned by
get_single_layer for assertions, and add these tests adjacent to the existing
parsing tests so they exercise lines handling artifact_type and the
layer-selection branches.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/fls/oci/manifest.rs`:
- Around line 145-163: The early-return and artifact_type match currently accept
any layer regardless of media_type; update the selection logic in manifest.rs so
every successful path validates the layer.media_type against the allowed
flashable disk types (e.g., check starts_with("application/vnd.automotive.disk")
or an equivalent allowed list) before returning; specifically, when
m.layers.len() == 1 verify m.layers[0].media_type is flashable, when matching
via m.artifact_type ensure the found layer also has a flashable media_type, and
keep the existing fallback that finds the first layer whose media_type
starts_with the disk prefix.

---

Nitpick comments:
In `@src/fls/oci/manifest.rs`:
- Around line 67-69: Add three focused unit tests for Manifest::get_single_layer
covering the new selection branches: (1) create a manifest with artifact_type
set and layers such that the correct layer is chosen then assert
get_single_layer returns that layer, (2) create a manifest with a single layer
whose mediaType is not a disk type and assert get_single_layer returns the
expected rejection/error, and (3) create a manifest with no matching layers and
assert get_single_layer returns the no-match error. Locate the Manifest struct
and the get_single_layer method to construct test Manifests and expected Layer
descriptors, use the same error types returned by get_single_layer for
assertions, and add these tests adjacent to the existing parsing tests so they
exercise lines handling artifact_type and the layer-selection branches.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 55bbc641-f85a-4511-a0be-17bb83c99ad0

📥 Commits

Reviewing files that changed from the base of the PR and between 60e5a9b and eab5e55.

📒 Files selected for processing (1)
  • src/fls/oci/manifest.rs

Comment on lines +145 to +163
if m.layers.len() == 1 {
return Ok(&m.layers[0]);
}

// If artifactType is set, find the layer matching it
if let Some(ref artifact_type) = m.artifact_type {
if let Some(layer) = m.layers.iter().find(|l| l.media_type == *artifact_type) {
return Ok(layer);
}
}

// Fall back to the first disk image layer
if let Some(layer) = m
.layers
.iter()
.find(|l| l.media_type.starts_with("application/vnd.automotive.disk"))
{
return Ok(layer);
}
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Validate all successful paths against the flashable media types.

Line 145 returns the only layer before any media-type check, and Lines 149-153 will also accept any artifact_type match. That still lets a non-disk blob through this path, which is exactly what this PR is trying to prevent.

Minimal fix
             Manifest::Image(ref m) => {
+                let is_flashable = |layer: &Descriptor| {
+                    layer.media_type.starts_with("application/vnd.automotive.disk")
+                };
+
                 if m.layers.is_empty() {
                     return Err("Manifest has no layers".to_string());
                 }
 
                 if m.layers.len() == 1 {
-                    return Ok(&m.layers[0]);
+                    let layer = &m.layers[0];
+                    return if is_flashable(layer) {
+                        Ok(layer)
+                    } else {
+                        Err(format!("Layer media type '{}' is not flashable", layer.media_type))
+                    };
                 }
 
                 // If artifactType is set, find the layer matching it
                 if let Some(ref artifact_type) = m.artifact_type {
-                    if let Some(layer) = m.layers.iter().find(|l| l.media_type == *artifact_type) {
+                    if let Some(layer) = m.layers.iter().find(|l| {
+                        l.media_type == *artifact_type && is_flashable(l)
+                    }) {
                         return Ok(layer);
                     }
                 }
 
                 // Fall back to the first disk image layer
                 if let Some(layer) = m
                     .layers
                     .iter()
-                    .find(|l| l.media_type.starts_with("application/vnd.automotive.disk"))
+                    .find(|l| is_flashable(l))
                 {
                     return Ok(layer);
                 }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/fls/oci/manifest.rs` around lines 145 - 163, The early-return and
artifact_type match currently accept any layer regardless of media_type; update
the selection logic in manifest.rs so every successful path validates the
layer.media_type against the allowed flashable disk types (e.g., check
starts_with("application/vnd.automotive.disk") or an equivalent allowed list)
before returning; specifically, when m.layers.len() == 1 verify
m.layers[0].media_type is flashable, when matching via m.artifact_type ensure
the found layer also has a flashable media_type, and keep the existing fallback
that finds the first layer whose media_type starts_with the disk prefix.

@bennyz bennyz requested a review from mangelajo March 18, 2026 18:15
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.

1 participant