Skip to content

ride4: add support for fastboot erase#851

Merged
mangelajo merged 1 commit into
mainfrom
erase-recoveryinfo
Jul 7, 2026
Merged

ride4: add support for fastboot erase#851
mangelajo merged 1 commit into
mainfrom
erase-recoveryinfo

Conversation

@bennyz

@bennyz bennyz commented Jul 2, 2026

Copy link
Copy Markdown
Member

Support fastboot erase operation via the ride4 driver.
This allows erasing partitions the following way:

j storage erase recoveryinfo

@coderabbitai

coderabbitai Bot commented Jul 2, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

The PR adds erase_partition support for RideSX in the driver, client, CLI, tests, and README. It also documents the new erase step in the flashing workflow and expands error-path coverage.

Changes

Erase Partition Feature

Layer / File(s) Summary
Driver-level erase_partition implementation
python/packages/jumpstarter-driver-ridesx/jumpstarter_driver_ridesx/driver.py
Adds erase_timeout and an exported erase_partition method that validates input, runs fastboot erase, and maps subprocess failures to runtime errors.
Client method and CLI subcommand
python/packages/jumpstarter-driver-ridesx/jumpstarter_driver_ridesx/client.py
Adds RideSXClient.erase_partition and a new j storage erase <partition> CLI command that calls it and prints the returned status.
Erase partition test coverage
python/packages/jumpstarter-driver-ridesx/jumpstarter_driver_ridesx/driver_test.py
Adds tests for successful erase, fastboot errors, timeout handling, missing fastboot, and empty partition validation.
README documentation updates
python/packages/jumpstarter-driver-ridesx/README.md
Updates the flashing workflow, adds erase-partition usage, and documents erase_partition in the client API list.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Sequence Diagram(s)

sequenceDiagram
  participant User
  participant RideSXClient
  participant RideSXDriver
  participant fastboot

  User->>RideSXClient: j storage erase <partition>
  RideSXClient->>RideSXDriver: erase_partition(device_id, partition)
  RideSXDriver->>fastboot: fastboot -s device_id erase partition
  fastboot-->>RideSXDriver: status / stdout / stderr
  RideSXDriver-->>RideSXClient: result
  RideSXClient-->>User: echoed status
Loading

Suggested reviewers: bkhizgiy

Poem

I nibbled the partition, crisp and bright,
fastboot hummed and hopped through the night.
The client chirped, the driver did too,
“Erase complete!” in a bunny-blue hue.
🐇

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately summarizes the main change: adding fastboot erase support to the ride4/RideSX driver.
Description check ✅ Passed The description matches the changeset by describing fastboot erase support and the new storage erase command.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch erase-recoveryinfo

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.

@bennyz bennyz added the build-pr-images/jumpstarter request to build only the jumpstarter image from PR label Jul 2, 2026
@github-actions

github-actions Bot commented Jul 2, 2026

Copy link
Copy Markdown

Container Images

The following container images have been built for this PR:

Image URI
jumpstarter quay.io/jumpstarter-dev/jumpstarter:pr-851

Images expire after 7 days.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

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 (3)
python/packages/jumpstarter-driver-ridesx/jumpstarter_driver_ridesx/client.py (1)

497-508: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

CLI erase discards the result and gives no user feedback or confirmation.

self.erase_partition(partition)'s return value is silently dropped, so a successful j storage erase prints nothing to confirm success. Additionally, erase is a destructive/irreversible operation with no confirmation prompt, unlike the risk typically associated with wiping a partition.

♻️ Proposed fix
         `@base.command`()
         `@click.argument`("partition")
-        def erase(partition):
+        `@click.option`("--yes", "-y", is_flag=True, help="Skip confirmation prompt")
+        def erase(partition, yes):
             """Erase a partition using fastboot.

             \b
             Examples:
               j storage erase recoveryinfo
               j storage erase userdata
             """
-            self.erase_partition(partition)
+            if not yes:
+                click.confirm(f"This will erase partition '{partition}'. Continue?", abort=True)
+            result = self.erase_partition(partition)
+            click.echo(f"Erased partition '{partition}': {result.get('status')}")
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@python/packages/jumpstarter-driver-ridesx/jumpstarter_driver_ridesx/client.py`
around lines 497 - 508, The CLI erase command in the erase function discards the
result of self.erase_partition(partition) and gives no confirmation to the user.
Update erase to capture the return value from erase_partition and print or echo
a clear success message when the operation completes, and add a confirmation
prompt before invoking the destructive erase action so accidental wipes are
prevented.
python/packages/jumpstarter-driver-ridesx/jumpstarter_driver_ridesx/driver.py (1)

346-346: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Hardcoded 120s timeout is inconsistent with other operation timeouts.

decompression_timeout, flash_timeout, and continue_timeout are all configurable dataclass fields (Lines 20-22), but the erase timeout is hardcoded inline. Consider adding an erase_timeout field for consistency and configurability.

♻️ Proposed fix
     decompression_timeout: int = field(default=15 * 60)  # 15 minutes
     flash_timeout: int = field(default=30 * 60)  # 30 minutes
     continue_timeout: int = field(default=20 * 60)  # 20 minutes
+    erase_timeout: int = field(default=120)  # 2 minutes
-            result = subprocess.run(cmd, capture_output=True, text=True, check=True, timeout=120)
+            result = subprocess.run(cmd, capture_output=True, text=True, check=True, timeout=self.erase_timeout)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@python/packages/jumpstarter-driver-ridesx/jumpstarter_driver_ridesx/driver.py`
at line 346, The erase operation in the subprocess.run call inside driver.py
uses a hardcoded 120-second timeout, unlike the other configurable timeouts. Add
an erase_timeout dataclass field alongside decompression_timeout, flash_timeout,
and continue_timeout, then update the erase path to use that field instead of
the inline constant in the method that runs the erase command.
python/packages/jumpstarter-driver-ridesx/jumpstarter_driver_ridesx/driver_test.py (1)

433-433: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Hoist repeated DriverError import to module top.

from jumpstarter.client.core import DriverError is re-imported inline in three separate test functions. Move it to the top-level imports once instead of duplicating per-test.

♻️ Suggested consolidation
+from jumpstarter.client.core import DriverError
+
 def test_erase_partition_failure(ridesx_driver):
     with serve(ridesx_driver) as client:
-        from jumpstarter.client.core import DriverError
-
         with patch("subprocess.run") as mock_subprocess:

(repeat removal for test_erase_partition_timeout and test_erase_partition_fastboot_not_found)

Also applies to: 447-447, 458-458

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@python/packages/jumpstarter-driver-ridesx/jumpstarter_driver_ridesx/driver_test.py`
at line 433, The test module is re-importing DriverError inside multiple test
functions instead of using a single top-level import. Move the import from
jumpstarter.client.core to the module-level imports in driver_test and remove
the repeated inline imports from test_erase_partition,
test_erase_partition_timeout, and test_erase_partition_fastboot_not_found so the
symbol is defined once and reused consistently.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In
`@python/packages/jumpstarter-driver-ridesx/jumpstarter_driver_ridesx/client.py`:
- Around line 36-51: The erase_partition flow leaves the device powered on,
unlike the flash paths that clean up afterward. Update erase_partition in
client.py to mirror the _execute_flash_operation behavior by calling
_power_off_if_available after the erase_partition call completes, while keeping
the existing fastboot detection and click.ClickException handling unchanged. Use
the erase_partition method and _power_off_if_available helper as the key places
to make the change.

---

Nitpick comments:
In
`@python/packages/jumpstarter-driver-ridesx/jumpstarter_driver_ridesx/client.py`:
- Around line 497-508: The CLI erase command in the erase function discards the
result of self.erase_partition(partition) and gives no confirmation to the user.
Update erase to capture the return value from erase_partition and print or echo
a clear success message when the operation completes, and add a confirmation
prompt before invoking the destructive erase action so accidental wipes are
prevented.

In
`@python/packages/jumpstarter-driver-ridesx/jumpstarter_driver_ridesx/driver_test.py`:
- Line 433: The test module is re-importing DriverError inside multiple test
functions instead of using a single top-level import. Move the import from
jumpstarter.client.core to the module-level imports in driver_test and remove
the repeated inline imports from test_erase_partition,
test_erase_partition_timeout, and test_erase_partition_fastboot_not_found so the
symbol is defined once and reused consistently.

In
`@python/packages/jumpstarter-driver-ridesx/jumpstarter_driver_ridesx/driver.py`:
- Line 346: The erase operation in the subprocess.run call inside driver.py uses
a hardcoded 120-second timeout, unlike the other configurable timeouts. Add an
erase_timeout dataclass field alongside decompression_timeout, flash_timeout,
and continue_timeout, then update the erase path to use that field instead of
the inline constant in the method that runs the erase command.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: c5bad5f9-51d5-4840-9463-6f5557152171

📥 Commits

Reviewing files that changed from the base of the PR and between d9705b7 and f0690ba.

📒 Files selected for processing (4)
  • python/packages/jumpstarter-driver-ridesx/README.md
  • python/packages/jumpstarter-driver-ridesx/jumpstarter_driver_ridesx/client.py
  • python/packages/jumpstarter-driver-ridesx/jumpstarter_driver_ridesx/driver.py
  • python/packages/jumpstarter-driver-ridesx/jumpstarter_driver_ridesx/driver_test.py

@bennyz bennyz marked this pull request as ready for review July 2, 2026 10:55
@bennyz bennyz force-pushed the erase-recoveryinfo branch from f0690ba to ae7b728 Compare July 2, 2026 12:13
@bennyz bennyz requested review from bkhizgiy and evakhoni July 2, 2026 12:33

self.logger.info(f"Erasing partition '{partition}' on device {device_id}")

cmd = ["fastboot", "-s", device_id, "erase", "--", partition]

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

why the -- between erase and partition?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

that's weird, i missed this hallucination but for some reason the operation worked correctly in the lab

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

yep, knowing you I suspected it was lab-tested but I was looking at the fastboot command and didn't seem to be needed.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

updated and retested, not sure why it worked though, an explanation could be that it tries to erase both "--" and "partition"

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
python/packages/jumpstarter-driver-ridesx/jumpstarter_driver_ridesx/driver.py (1)

330-363: 🔒 Security & Privacy | 🔵 Trivial | 💤 Low value

Consider guarding against argument/flag injection for partition and device_id.

subprocess.run here uses a list of args with no shell=True, so the static analysis CWE-78 flag on Line 347 is a false positive — there's no shell interpolation risk. However, partition and device_id are passed through unvalidated as fastboot CLI arguments; a value beginning with - (e.g. a leading-dash partition name) could be misinterpreted by fastboot as a flag instead of a positional argument. Given erase is destructive/irreversible, this is worth a stricter check than existing methods like flash_with_fastboot apply to partition_name/device_id.

🛡️ Optional stricter validation
         if not partition or not partition.strip():
             raise ValueError("Partition name cannot be empty")
+        if partition.startswith("-"):
+            raise ValueError(f"Invalid partition name: '{partition}'")
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@python/packages/jumpstarter-driver-ridesx/jumpstarter_driver_ridesx/driver.py`
around lines 330 - 363, The erase_partition method in driver.py should reject
fastboot arguments that could be interpreted as flags, not just empty values.
Add stricter validation for both device_id and partition in erase_partition so
they cannot start with a dash (matching the safer checks used in
flash_with_fastboot for partition_name/device_id), and keep the subprocess.run
call as a list-based invocation. Ensure any invalid input raises a clear
ValueError before building the fastboot command.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In
`@python/packages/jumpstarter-driver-ridesx/jumpstarter_driver_ridesx/driver.py`:
- Around line 330-363: The erase_partition method in driver.py should reject
fastboot arguments that could be interpreted as flags, not just empty values.
Add stricter validation for both device_id and partition in erase_partition so
they cannot start with a dash (matching the safer checks used in
flash_with_fastboot for partition_name/device_id), and keep the subprocess.run
call as a list-based invocation. Ensure any invalid input raises a clear
ValueError before building the fastboot command.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: b8a27215-f074-4dc9-8499-fc36d52ea902

📥 Commits

Reviewing files that changed from the base of the PR and between ae7b728 and 6a8a957.

📒 Files selected for processing (4)
  • python/packages/jumpstarter-driver-ridesx/README.md
  • python/packages/jumpstarter-driver-ridesx/jumpstarter_driver_ridesx/client.py
  • python/packages/jumpstarter-driver-ridesx/jumpstarter_driver_ridesx/driver.py
  • python/packages/jumpstarter-driver-ridesx/jumpstarter_driver_ridesx/driver_test.py
✅ Files skipped from review due to trivial changes (1)
  • python/packages/jumpstarter-driver-ridesx/README.md
🚧 Files skipped from review as they are similar to previous changes (2)
  • python/packages/jumpstarter-driver-ridesx/jumpstarter_driver_ridesx/client.py
  • python/packages/jumpstarter-driver-ridesx/jumpstarter_driver_ridesx/driver_test.py

@mangelajo mangelajo enabled auto-merge July 6, 2026 14:13
Support `fastboot erase` operation via the ride4 driver.
This allows erasing partitions the following way:

  j storage erase recoveryinfo

Signed-off-by: Benny Zlotnik <bzlotnik@redhat.com>
Assisted-by: claude-opus-4.6
@bennyz bennyz force-pushed the erase-recoveryinfo branch from 6a8a957 to ba4858e Compare July 7, 2026 04:49

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
python/packages/jumpstarter-driver-ridesx/jumpstarter_driver_ridesx/driver.py (1)

331-331: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Return type hint style inconsistency.

erase_partition uses the lowercase builtin generic dict[str, str], while other exported methods in this file (e.g. flash_with_fastboot at Line 178) use Dict[str, str] imported from typing. Consider aligning for consistency within the file.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@python/packages/jumpstarter-driver-ridesx/jumpstarter_driver_ridesx/driver.py`
at line 331, The return type annotation on erase_partition is inconsistent with
the rest of driver.py, since it uses the builtin generic dict[str, str] while
exported methods like flash_with_fastboot use typing.Dict[str, str]. Update
erase_partition to use the same Dict[str, str] style as the other public methods
in this file so the type hints are consistent.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In
`@python/packages/jumpstarter-driver-ridesx/jumpstarter_driver_ridesx/driver.py`:
- Line 331: The return type annotation on erase_partition is inconsistent with
the rest of driver.py, since it uses the builtin generic dict[str, str] while
exported methods like flash_with_fastboot use typing.Dict[str, str]. Update
erase_partition to use the same Dict[str, str] style as the other public methods
in this file so the type hints are consistent.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 11c0ea0f-b99b-42a8-8f2a-b2f49a7a1a89

📥 Commits

Reviewing files that changed from the base of the PR and between 6a8a957 and ba4858e.

📒 Files selected for processing (4)
  • python/packages/jumpstarter-driver-ridesx/README.md
  • python/packages/jumpstarter-driver-ridesx/jumpstarter_driver_ridesx/client.py
  • python/packages/jumpstarter-driver-ridesx/jumpstarter_driver_ridesx/driver.py
  • python/packages/jumpstarter-driver-ridesx/jumpstarter_driver_ridesx/driver_test.py
✅ Files skipped from review due to trivial changes (1)
  • python/packages/jumpstarter-driver-ridesx/README.md
🚧 Files skipped from review as they are similar to previous changes (2)
  • python/packages/jumpstarter-driver-ridesx/jumpstarter_driver_ridesx/client.py
  • python/packages/jumpstarter-driver-ridesx/jumpstarter_driver_ridesx/driver_test.py

@mangelajo mangelajo added this pull request to the merge queue Jul 7, 2026
Merged via the queue into main with commit d20709d Jul 7, 2026
31 checks passed
@mangelajo mangelajo deleted the erase-recoveryinfo branch July 7, 2026 05:53
@jumpstarter-backport-bot

Copy link
Copy Markdown

Successfully created backport PR for release-0.9:

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

backport release-0.9 build-pr-images/jumpstarter request to build only the jumpstarter image from PR

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants