Skip to content

Conversation

@richm
Copy link
Contributor

@richm richm commented Dec 31, 2025

Cause: The code did not check for missing or empty disks in the right place.

Consequence: The role would issue a strange error which did not indicate that the
problem is that no disks were specified.

Fix: Check for missing disks early and report appropriate error.

Result: The role will report an appropriate error message if no disks
are specified.

Signed-off-by: Rich Megginson rmeggins@redhat.com

Summary by Sourcery

Improve disk volume handling when no disks are specified and extend coverage with new storage tests.

Bug Fixes:

  • Prevent disk volume processing from assuming at least one disk and return no device when the disks list is missing or empty.

Tests:

  • Add regression test to verify the role fails with a clear error when no disks are specified for a volume.
  • Extend default test configuration to include a volume with an empty disks list.
  • Add generated NVMe and SCSI variants of multiple-partition DOS and GPT test playbooks.

Cause: The code did not check for missing or empty disks in the right place.

Consequence: The role would issue a strange error which did not indicate that the
problem is that no disks were specified.

Fix: Check for missing disks early and report appropriate error.

Result: The role will report an appropriate error message if no disks
are specified.

Signed-off-by: Rich Megginson <rmeggins@redhat.com>
@sourcery-ai
Copy link

sourcery-ai bot commented Dec 31, 2025

Reviewer's Guide

Adds an early check in BlivetDiskVolume to handle volumes with no disks specified by returning None as the device id, and extends the Ansible test suite to cover the no-disks error case plus generated tests for multiple partition layouts on NVMe and SCSI.

Class diagram for updated BlivetDiskVolume device id handling

classDiagram
    class BlivetVolume {
        +dict _volume
        +string name
        +string id
        +get_device_id()
        +_type_check()
    }

    class BlivetDiskVolume {
        +dict _volume
        +string name
        +string id
        +_get_device_id() string
        +_type_check()
    }

    BlivetVolume <|-- BlivetDiskVolume

    BlivetVolume : _volume holds volume configuration
    BlivetDiskVolume : blivet_device_class = devices.DiskDevice
    BlivetDiskVolume : _get_device_id() checks _volume.disks
    BlivetDiskVolume : if _volume.disks missing or empty returns None
    BlivetDiskVolume : if _volume.disks nonempty returns first disk identifier
Loading

Flow diagram for BlivetDiskVolume _get_device_id no-disks error handling

flowchart TD
    A[Start _get_device_id] --> B[Read disks from _volume using key disks with default empty list]
    B --> C{Is disks empty?}
    C -- Yes --> D[Return None as device id]
    C -- No --> E[Select first element of disks]
    E --> F[Return first disk as device id]
    D --> G[Caller detects missing device id and reports no disks specified error]
    F --> H[Caller continues with disk operations]
Loading

File-Level Changes

Change Details Files
Handle volumes with no disks specified in BlivetDiskVolume and adjust type checking behavior accordingly.
  • Retrieve the volume's disks list with a default of an empty list instead of assuming the key exists.
  • Return None from _get_device_id when the disks list is empty, avoiding indexing errors or misleading behavior.
  • Preserve existing behavior of returning the first disk when at least one disk is provided, allowing downstream error reporting to surface the correct 'no disks specified' message.
library/blivet.py
Add regression tests to verify the role fails with the correct error when no disks are specified and to configure a default play for an empty-disk volume.
  • Add a test case that invokes verify-role-failed.yml expecting the 'no disks specified for volume' error when a volume is defined without disks.
  • Update the default test playbook to define a disk-type volume with an explicitly empty disks array and safe mode disabled, ensuring the new error path is exercised.
tests/tests_disk_errors.yml
tests/tests_default.yml
Introduce generated tests to run existing multiple-partition scenarios against both NVMe and SCSI interfaces.
  • Create NVMe variants of the DOS and GPT multiple-partition tests that set storage_test_use_interface to 'nvme' before importing the shared playbooks.
  • Create SCSI variants of the DOS and GPT multiple-partition tests that set storage_test_use_interface to 'scsi' before importing the shared playbooks.
  • Tag the new playbooks with interface-specific tags to allow selective test execution by interface type.
tests/tests_create_multiple_partitions_dos_nvme_generated.yml
tests/tests_create_multiple_partitions_dos_scsi_generated.yml
tests/tests_create_multiple_partitions_gpt_nvme_generated.yml
tests/tests_create_multiple_partitions_gpt_scsi_generated.yml

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

Copy link

@sourcery-ai sourcery-ai bot left a comment

Choose a reason for hiding this comment

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

Hey - I've found 1 issue, and left some high level feedback:

  • In BlivetDiskVolume._get_device_id, you build a disks local variable but then ignore it in the return; consider using disks[0] for consistency and to avoid duplicating the lookup logic.
  • Returning None from _get_device_id to represent "no disks" relies on implicit behavior further up the stack; consider handling this case more explicitly (e.g., by raising a clear error or performing the validation at the call site) so the failure mode is easier to follow in the code.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- In `BlivetDiskVolume._get_device_id`, you build a `disks` local variable but then ignore it in the return; consider using `disks[0]` for consistency and to avoid duplicating the lookup logic.
- Returning `None` from `_get_device_id` to represent "no disks" relies on implicit behavior further up the stack; consider handling this case more explicitly (e.g., by raising a clear error or performing the validation at the call site) so the failure mode is easier to follow in the code.

## Individual Comments

### Comment 1
<location> `library/blivet.py:943-944` </location>
<code_context>
     blivet_device_class = devices.DiskDevice

     def _get_device_id(self):
+        disks = self._volume.get('disks', [])
+        if not disks:
+            return None
         return self._volume['disks'][0]
</code_context>

<issue_to_address>
**question (bug_risk):** Clarify the intended behavior change when `disks` is missing or empty (now returning `None`).

Previously this would raise a `KeyError`/`IndexError` when `disks` was missing or empty; now it returns `None`. Please confirm all callers either expect `None` as a valid "no device" value or explicitly handle it, rather than relying on the earlier exception behavior.
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Comment on lines +943 to +944
disks = self._volume.get('disks', [])
if not disks:
Copy link

Choose a reason for hiding this comment

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

question (bug_risk): Clarify the intended behavior change when disks is missing or empty (now returning None).

Previously this would raise a KeyError/IndexError when disks was missing or empty; now it returns None. Please confirm all callers either expect None as a valid "no device" value or explicitly handle it, rather than relying on the earlier exception behavior.

@codecov
Copy link

codecov bot commented Dec 31, 2025

Codecov Report

❌ Patch coverage is 0% with 3 lines in your changes missing coverage. Please review.
✅ Project coverage is 10.34%. Comparing base (59fd1c6) to head (137304f).
⚠️ Report is 98 commits behind head on main.

Files with missing lines Patch % Lines
library/blivet.py 0.00% 3 Missing ⚠️

❗ There is a different number of reports uploaded between BASE (59fd1c6) and HEAD (137304f). Click for more details.

HEAD has 1 upload less than BASE
Flag BASE (59fd1c6) HEAD (137304f)
sanity 1 0
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #575      +/-   ##
==========================================
- Coverage   16.54%   10.34%   -6.21%     
==========================================
  Files           2        8       +6     
  Lines         284     2020    +1736     
  Branches       79        0      -79     
==========================================
+ Hits           47      209     +162     
- Misses        237     1811    +1574     
Flag Coverage Δ
sanity ?

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@richm
Copy link
Contributor Author

richm commented Dec 31, 2025

[citest]

@richm
Copy link
Contributor Author

richm commented Jan 2, 2026

[citest]

@richm
Copy link
Contributor Author

richm commented Jan 2, 2026

testing farm ci is broken :-( investigating

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.

2 participants