Skip to content

Conversation

@bennyz
Copy link
Member

@bennyz bennyz commented Dec 17, 2025

add --insecure-tls

Summary by CodeRabbit

  • New Features
    • Support downloading images from HTTP(S) sources and provisioning them for flashing.
    • Added an --insecure-tls option to control TLS verification when accessing remote resources.
    • Flashing flow now accepts per-target mappings and can handle remote URLs when preparing partitions.
    • CLI flash command updated to provide target-mapping support and expose the insecure-tls option.

✏️ Tip: You can customize this high-level summary in your review settings.

add --insecure-tls

Signed-off-by: Benny Zlotnik <[email protected]>
@netlify
Copy link

netlify bot commented Dec 17, 2025

Deploy Preview for jumpstarter-docs ready!

Name Link
🔨 Latest commit b17d46e
🔍 Latest deploy log https://app.netlify.com/projects/jumpstarter-docs/deploys/694a5b5f1ba15400072034ec
😎 Deploy Preview https://deploy-preview-783--jumpstarter-docs.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Dec 17, 2025

Walkthrough

Adds HTTP(S) download support and an insecure TLS option to the RideSX driver client. New helpers detect and download HTTP URLs; upload and flashing flows accept and propagate insecure_tls. CLI replaces the generic flash command with a custom one that supports target mapping and --insecure-tls.

Changes

Cohort / File(s) Summary
HTTP support
packages/jumpstarter-driver-ridesx/jumpstarter_driver_ridesx/client.py
Added _is_http_url() to detect http(s) URLs and _download_http_to_storage() to download remote files (aiohttp) with optional insecure TLS.
Upload & flash flow
packages/jumpstarter-driver-ridesx/jumpstarter_driver_ridesx/client.py
Extended _upload_file_if_needed() signature with insecure_tls; supports downloading remote HTTP(S) URLs into storage. Added flash_images() with insecure_tls and updated flash() to accept/forward insecure_tls.
CLI surface
packages/jumpstarter-driver-ridesx/jumpstarter_driver_ridesx/client.py
cli() suppresses generic flash command and registers a custom flash command with --target/-t and --insecure-tls, including target-spec mapping logic.

Sequence Diagram

sequenceDiagram
    participant User as User/CLI
    participant Client as RideSXClient
    participant HTTP as HTTP(S) Source
    participant Storage as Storage/Operator
    participant Device as Device

    Note over User,Client: User invokes flash with path(s) and insecure_tls flag
    User->>Client: flash(path or targets, insecure_tls)
    Client->>Client: determine target(s) and partition(s)
    loop per file/partition
        Client->>Client: _is_http_url(path)?
        alt HTTP(S) URL
            Client->>HTTP: download (insecure_tls?)
            HTTP-->>Client: response bytes
            Client->>Storage: write file to storage
            Storage-->>Client: storage path/URL
        else Local or operator path
            Client->>Storage: _upload_file_if_needed(path, operator, insecure_tls)
            Storage-->>Client: storage path/URL
        end
        Client->>Client: flash_images(partitions, operators, insecure_tls)
        Client->>Device: stream image to partition
        Device-->>Client: flash result
    end
    Client-->>User: aggregate results / complete
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 45.45% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely summarizes the main changes: adding HTTP support and insecure HTTPS (TLS) capability to the ridesx driver.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

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.

@bennyz bennyz requested a review from mangelajo December 17, 2025 16:18
Copy link
Contributor

@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: 3

📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between b05be84 and 6d3203f.

📒 Files selected for processing (1)
  • packages/jumpstarter-driver-ridesx/jumpstarter_driver_ridesx/client.py (7 hunks)
🧰 Additional context used
📓 Path-based instructions (3)
packages/jumpstarter-driver-*/jumpstarter_driver_*/client.py

📄 CodeRabbit inference engine (.cursor/rules/creating-new-drivers.mdc)

Driver client CLIs should either implement known classes that provide a CLI interface, or implement their own CLI interface. Use CompositeClient from jumpstarter_driver_composite.client for composite drivers with child drivers.

Files:

  • packages/jumpstarter-driver-ridesx/jumpstarter_driver_ridesx/client.py
packages/jumpstarter-driver-**/jumpstarter_driver_**/*.py

📄 CodeRabbit inference engine (.cursor/rules/creating-new-drivers.mdc)

Driver implementations should follow existing code style validated with make lint (fix with make lint-fix), perform static type checking with make ty-pkg-${package_name}, add comprehensive tests, and verify all tests pass with make test-pkg-${package_name} or make test

Files:

  • packages/jumpstarter-driver-ridesx/jumpstarter_driver_ridesx/client.py
**/*.py

📄 CodeRabbit inference engine (.cursor/rules/project-structure.mdc)

Ruff should be used for code formatting and linting, excluding jumpstarter-protocol package

Files:

  • packages/jumpstarter-driver-ridesx/jumpstarter_driver_ridesx/client.py
🧠 Learnings (2)
📓 Common learnings
Learnt from: bennyz
Repo: jumpstarter-dev/jumpstarter PR: 241
File: packages/jumpstarter-driver-tftp/jumpstarter_driver_tftp/client.py:52-60
Timestamp: 2025-01-29T11:52:50.888Z
Learning: The TFTP driver (driver.py) already handles error cases and file path security, so the client (client.py) doesn't need to duplicate these safeguards.
📚 Learning: 2025-11-27T09:58:41.875Z
Learnt from: CR
Repo: jumpstarter-dev/jumpstarter PR: 0
File: .cursor/rules/creating-new-drivers.mdc:0-0
Timestamp: 2025-11-27T09:58:41.875Z
Learning: Applies to packages/jumpstarter-driver-*/jumpstarter_driver_*/client.py : Driver client CLIs should either implement known classes that provide a CLI interface, or implement their own CLI interface. Use `CompositeClient` from `jumpstarter_driver_composite.client` for composite drivers with child drivers.

Applied to files:

  • packages/jumpstarter-driver-ridesx/jumpstarter_driver_ridesx/client.py
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (11)
  • GitHub Check: Redirect rules - jumpstarter-docs
  • GitHub Check: Header rules - jumpstarter-docs
  • GitHub Check: Pages changed - jumpstarter-docs
  • GitHub Check: build
  • GitHub Check: pytest-matrix (ubuntu-24.04, 3.11)
  • GitHub Check: pytest-matrix (macos-15, 3.11)
  • GitHub Check: pytest-matrix (ubuntu-24.04, 3.13)
  • GitHub Check: pytest-matrix (ubuntu-24.04, 3.12)
  • GitHub Check: pytest-matrix (macos-15, 3.12)
  • GitHub Check: e2e
  • GitHub Check: pytest-matrix (macos-15, 3.13)
🔇 Additional comments (2)
packages/jumpstarter-driver-ridesx/jumpstarter_driver_ridesx/client.py (2)

91-126: LGTM!

The insecure_tls parameter is properly propagated through the flash workflow.


128-167: LGTM!

The insecure_tls parameter integration in the flash method is correct.

Comment on lines 44 to 48
connector = aiohttp.TCPConnector(ssl=ssl_context)
async with aiohttp.ClientSession(connector=connector) as session:
async with session.get(url) as response:
response.raise_for_status()
return await response.read()
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Add timeout to prevent indefinite hangs.

The HTTP request has no timeout configured. If the server is slow or unresponsive, this could block indefinitely.

-            connector = aiohttp.TCPConnector(ssl=ssl_context)
-            async with aiohttp.ClientSession(connector=connector) as session:
-                async with session.get(url) as response:
+            timeout = aiohttp.ClientTimeout(total=300)  # 5 minutes
+            connector = aiohttp.TCPConnector(ssl=ssl_context)
+            async with aiohttp.ClientSession(connector=connector, timeout=timeout) as session:
+                async with session.get(url) as response:
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
connector = aiohttp.TCPConnector(ssl=ssl_context)
async with aiohttp.ClientSession(connector=connector) as session:
async with session.get(url) as response:
response.raise_for_status()
return await response.read()
timeout = aiohttp.ClientTimeout(total=300) # 5 minutes
connector = aiohttp.TCPConnector(ssl=ssl_context)
async with aiohttp.ClientSession(connector=connector, timeout=timeout) as session:
async with session.get(url) as response:
response.raise_for_status()
return await response.read()
🤖 Prompt for AI Agents
In packages/jumpstarter-driver-ridesx/jumpstarter_driver_ridesx/client.py around
lines 44 to 48, the aiohttp request uses no timeout and may hang indefinitely;
add a timeout by creating an aiohttp.ClientTimeout (e.g., set total and/or
connect/read timeouts) and supply it to the ClientSession (or pass timeout=...
to session.get) so the request fails fast on slow/unresponsive servers; ensure
you handle the timeout exception (asyncio.TimeoutError or
aiohttp.ClientTimeoutError) appropriately where this function is called.

if not file:
raise click.ClickException("FILE argument is required unless --target/-t is used")

self.flash(file[0], target=None, insecure_tls=insecure_tls)
Copy link
Contributor

@coderabbitai coderabbitai bot Dec 17, 2025

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

Bug: Invalid keyword argument target will cause TypeError.

The flash method signature uses partition, not target. This will raise a TypeError: flash() got an unexpected keyword argument 'target' at runtime when flashing a single file via CLI.

-            self.flash(file[0], target=None, insecure_tls=insecure_tls)
+            self.flash(file[0], partition=None, insecure_tls=insecure_tls)

However, note that passing partition=None with a single file path will still fail validation at line 141-142 ("'partition' must be provided"). You may need to either require the partition argument in the CLI or update the logic. Consider:

-        @click.argument("file", nargs=-1, required=False)
+        @click.argument("file", nargs=1, required=False)
+        @click.option("--partition", "-p", help="Partition name for single file flash")
         @click.option(
             "--target",
             "-t",
             "target_specs",
             multiple=True,
             help="name:file",
         )
         @click.option("--insecure-tls", is_flag=True, help="Skip TLS certificate verification")
-        def flash(file, target_specs, insecure_tls):
+        def flash(file, partition, target_specs, insecure_tls):
             """Flash image to DUT"""
             if target_specs:
                 # ... existing target_specs handling ...
                 return

             if not file:
                 raise click.ClickException("FILE argument is required unless --target/-t is used")

-            self.flash(file[0], target=None, insecure_tls=insecure_tls)
+            if not partition:
+                raise click.ClickException("--partition/-p is required when flashing a single file")
+            self.flash(file[0], partition=partition, insecure_tls=insecure_tls)
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
self.flash(file[0], target=None, insecure_tls=insecure_tls)
self.flash(file[0], partition=None, insecure_tls=insecure_tls)
🤖 Prompt for AI Agents
packages/jumpstarter-driver-ridesx/jumpstarter_driver_ridesx/client.py around
line 206: the call uses an invalid keyword `target` when invoking flash, causing
a TypeError; change the call to pass the correct keyword `partition` (i.e., call
flash with partition=...) and then resolve the subsequent validation issue at
lines ~141-142 by either enforcing that the CLI requires a partition when
flashing a single file (add/validate the CLI flag and surface an error) or
update the validation to allow partition=None when a single-file flash is
supported (adjust the checks and error message accordingly).

Copy link
Member Author

Choose a reason for hiding this comment

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

why does this work:

j storage flash -t boot_a:http://10.47.238.41:8000/aboot.img -t system_a:http://10.47.238.41:8000/rootfs.simg.xz

Copy link
Contributor

Choose a reason for hiding this comment

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

@bennyz, great catch! Your command works perfectly because it uses the -t/--target option. Let me explain why:

When you use -t boot_a:http://... -t system_a:http://..., the CLI code takes this path:

if target_specs:
    mapping: dict[str, str] = {}
    for spec in target_specs:
        # ... parse spec ...
        mapping[name] = img
    self.flash(mapping, insecure_tls=insecure_tls)  # ✅ Passes a dict
    return

This calls self.flash() with a dictionary as the first parameter, which is perfectly valid since the flash method signature accepts path: str | Dict[str, str]. When a dict is passed, it takes this branch in the method:

if isinstance(path, dict):
    partitions = path  # ✅ Works correctly
    operators = operator if isinstance(operator, dict) else None

The bug I flagged only affects the non--t usage path (the single-file case at line 206):

self.flash(file[0], target=None, insecure_tls=insecure_tls)  # ❌ Invalid keyword `target`

This line uses target=None instead of partition=None, which would cause a TypeError. But since your command uses -t, it never hits this problematic line.

So your workflow is fine! The issue only matters if someone tries to flash a single file without using the -t option (which would also fail validation anyway since partition=None isn't handled).


🧠 Learnings used
Learnt from: CR
Repo: jumpstarter-dev/jumpstarter PR: 0
File: .cursor/rules/creating-new-drivers.mdc:0-0
Timestamp: 2025-11-27T09:58:41.875Z
Learning: Applies to packages/jumpstarter-driver-*/jumpstarter_driver_*/client.py : Driver client CLIs should either implement known classes that provide a CLI interface, or implement their own CLI interface. Use `CompositeClient` from `jumpstarter_driver_composite.client` for composite drivers with child drivers.

Learnt from: mangelajo
Repo: jumpstarter-dev/jumpstarter PR: 735
File: packages/jumpstarter-driver-flashers/jumpstarter_driver_flashers/client.py:100-101
Timestamp: 2025-11-05T13:31:39.304Z
Learning: In packages/jumpstarter-driver-flashers/jumpstarter_driver_flashers/client.py, the `flash()` method and its CLI command intentionally have different defaults for `fls_version`: the method defaults to `""` (empty string) while the CLI defaults to `"0.1.5"`. This is by design to provide CLI users with a convenient default while keeping the programmatic API ready for when FLS is included in the flasher images.

Learnt from: mangelajo
Repo: jumpstarter-dev/jumpstarter PR: 735
File: packages/jumpstarter-driver-flashers/jumpstarter_driver_flashers/client.py:476-486
Timestamp: 2025-11-05T13:33:24.741Z
Learning: In packages/jumpstarter-driver-flashers/jumpstarter_driver_flashers/client.py, the FLS flasher download in _flash_with_fls() hardcodes "aarch64-linux" architecture because the flasher always targets ARM devices currently.

Learnt from: CR
Repo: jumpstarter-dev/jumpstarter PR: 0
File: .cursor/rules/project-structure.mdc:0-0
Timestamp: 2025-11-27T09:58:55.346Z
Learning: Applies to packages/jumpstarter-driver-*/jumpstarter_driver_*/ : Driver packages must implement a `client.py` file containing the client implementation

Learnt from: mangelajo
Repo: jumpstarter-dev/jumpstarter PR: 735
File: packages/jumpstarter-driver-flashers/jumpstarter_driver_flashers/client.py:15-15
Timestamp: 2025-11-05T13:45:58.271Z
Learning: In packages/jumpstarter-driver-flashers/jumpstarter_driver_flashers/client.py, pexpect is intentionally used as a transitive dependency through the jumpstarter-driver-pyserial package. The flashers package does not declare pexpect as a direct dependency because the pyserial driver package is intended to control the pexpect version.

Learnt from: mangelajo
Repo: jumpstarter-dev/jumpstarter PR: 339
File: packages/jumpstarter-driver-flashers/jumpstarter_driver_flashers/client.py:349-349
Timestamp: 2025-03-14T16:05:14.577Z
Learning: The `_upload_artifact` method in `BaseFlasherClient` class should call `write_from_path` with the calculated filename parameter: `storage.write_from_path(filename, path, operator=operator)` instead of `storage.write_from_path(path, operator=operator)`.

Copy link
Member Author

Choose a reason for hiding this comment

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

so no need to change?

Copy link
Contributor

Choose a reason for hiding this comment

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

@bennyz, your current workflow is perfectly fine and doesn't need to change! The -t option path works correctly.

However, there is still a bug in the code that would affect anyone trying to use the single-file syntax (without -t). The line:

self.flash(file[0], target=None, insecure_tls=insecure_tls)

uses an invalid keyword target instead of partition, which would cause a TypeError at runtime.

Should it be fixed? That depends on your intent:

  • If the -t option is the only supported way to flash (which seems like the main use case), you could remove the single-file code path entirely or add a clearer error message
  • If single-file flashing should work, the bug needs fixing (change target=None to partition=None, but also handle that partition=None would fail validation)

Looking at the CLI design with file as an argument, it seems like single-file usage was intended to be supported. I'd recommend fixing it for completeness, even if it's not your primary use case. Otherwise, users will hit a confusing error.

Would you like me to suggest how to handle the single-file case, or would you prefer to remove that code path entirely?


🧠 Learnings used
Learnt from: CR
Repo: jumpstarter-dev/jumpstarter PR: 0
File: .cursor/rules/creating-new-drivers.mdc:0-0
Timestamp: 2025-11-27T09:58:41.875Z
Learning: Applies to packages/jumpstarter-driver-*/jumpstarter_driver_*/client.py : Driver client CLIs should either implement known classes that provide a CLI interface, or implement their own CLI interface. Use `CompositeClient` from `jumpstarter_driver_composite.client` for composite drivers with child drivers.

Learnt from: mangelajo
Repo: jumpstarter-dev/jumpstarter PR: 735
File: packages/jumpstarter-driver-flashers/jumpstarter_driver_flashers/client.py:100-101
Timestamp: 2025-11-05T13:31:39.304Z
Learning: In packages/jumpstarter-driver-flashers/jumpstarter_driver_flashers/client.py, the `flash()` method and its CLI command intentionally have different defaults for `fls_version`: the method defaults to `""` (empty string) while the CLI defaults to `"0.1.5"`. This is by design to provide CLI users with a convenient default while keeping the programmatic API ready for when FLS is included in the flasher images.

Learnt from: mangelajo
Repo: jumpstarter-dev/jumpstarter PR: 735
File: packages/jumpstarter-driver-flashers/jumpstarter_driver_flashers/client.py:476-486
Timestamp: 2025-11-05T13:33:24.741Z
Learning: In packages/jumpstarter-driver-flashers/jumpstarter_driver_flashers/client.py, the FLS flasher download in _flash_with_fls() hardcodes "aarch64-linux" architecture because the flasher always targets ARM devices currently.

Learnt from: CR
Repo: jumpstarter-dev/jumpstarter PR: 0
File: .cursor/rules/project-structure.mdc:0-0
Timestamp: 2025-11-27T09:58:55.346Z
Learning: Applies to packages/jumpstarter-driver-*/jumpstarter_driver_*/ : Driver packages must implement a `client.py` file containing the client implementation

Learnt from: mangelajo
Repo: jumpstarter-dev/jumpstarter PR: 735
File: packages/jumpstarter-driver-flashers/jumpstarter_driver_flashers/client.py:15-15
Timestamp: 2025-11-05T13:45:58.271Z
Learning: In packages/jumpstarter-driver-flashers/jumpstarter_driver_flashers/client.py, pexpect is intentionally used as a transitive dependency through the jumpstarter-driver-pyserial package. The flashers package does not declare pexpect as a direct dependency because the pyserial driver package is intended to control the pexpect version.

Learnt from: mangelajo
Repo: jumpstarter-dev/jumpstarter PR: 339
File: packages/jumpstarter-driver-flashers/jumpstarter_driver_flashers/client.py:349-349
Timestamp: 2025-03-14T16:05:14.577Z
Learning: The `_upload_artifact` method in `BaseFlasherClient` class should call `write_from_path` with the calculated filename parameter: `storage.write_from_path(filename, path, operator=operator)` instead of `storage.write_from_path(path, operator=operator)`.

Signed-off-by: Benny Zlotnik <[email protected]>
Copy link
Contributor

@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

♻️ Duplicate comments (3)
packages/jumpstarter-driver-ridesx/jumpstarter_driver_ridesx/client.py (3)

42-48: Critical: Add timeout to prevent indefinite hangs.

The aiohttp request lacks a timeout configuration. If the server is unresponsive or slow, the download could block indefinitely.

🔎 Proposed fix
+            timeout = aiohttp.ClientTimeout(total=300)  # 5 minutes
             connector = aiohttp.TCPConnector(ssl=ssl_context)
-            async with aiohttp.ClientSession(connector=connector) as session:
+            async with aiohttp.ClientSession(connector=connector, timeout=timeout) as session:
                 async with session.get(url) as response:

210-210: Critical: Invalid keyword argument will cause TypeError.

Line 210 uses target=None but the flash method signature expects partition. This will raise TypeError: flash() got an unexpected keyword argument 'target' at runtime. Additionally, passing partition=None will fail validation at lines 145-146.

🔎 Proposed fix

Add a --partition option to the CLI and validate it:

         @base.command()
         @click.argument("file", nargs=-1, required=False)
+        @click.option("--partition", "-p", help="Partition name for single file flash")
         @click.option(
             "--target",
             "-t",
             "target_specs",
             multiple=True,
             help="name:file",
         )
         @click.option("--insecure-tls", is_flag=True, help="Skip TLS certificate verification")
-        def flash(file, target_specs, insecure_tls):
+        def flash(file, partition, target_specs, insecure_tls):
             """Flash image to DUT"""
             if target_specs:
                 mapping: dict[str, str] = {}
                 for spec in target_specs:
                     if ":" not in spec:
                         raise click.ClickException(f"Invalid target spec '{spec}', expected name:file")
                     name, img = spec.split(":", 1)
                     mapping[name] = img
                 self.flash(mapping, insecure_tls=insecure_tls)
                 return

             if not file:
                 raise click.ClickException("FILE argument is required unless --target/-t is used")

-            self.flash(file[0], target=None, insecure_tls=insecure_tls)
+            if not partition:
+                raise click.ClickException("--partition/-p is required when flashing a single file")
+            self.flash(file[0], partition=partition, insecure_tls=insecure_tls)

186-210: Minor: Multiple files silently ignored.

The CLI accepts multiple files via nargs=-1 but only uses file[0]. If users provide multiple files without --target, the extra files will be silently ignored, which could be confusing.

Consider either:

  1. Change to nargs=1 if only single file is supported
  2. Raise an error if len(file) > 1 without target specs
🔎 Proposed fix (option 1)
-        @click.argument("file", nargs=-1, required=False)
+        @click.argument("file", nargs=1, required=False)
📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 6d3203f and b4e85c4.

📒 Files selected for processing (1)
  • packages/jumpstarter-driver-ridesx/jumpstarter_driver_ridesx/client.py
🧰 Additional context used
📓 Path-based instructions (3)
packages/jumpstarter-driver-*/jumpstarter_driver_*/client.py

📄 CodeRabbit inference engine (.cursor/rules/creating-new-drivers.mdc)

Driver client CLIs should either implement known classes that provide a CLI interface, or implement their own CLI interface. Use CompositeClient from jumpstarter_driver_composite.client for composite drivers with child drivers.

Files:

  • packages/jumpstarter-driver-ridesx/jumpstarter_driver_ridesx/client.py
packages/jumpstarter-driver-**/jumpstarter_driver_**/*.py

📄 CodeRabbit inference engine (.cursor/rules/creating-new-drivers.mdc)

Driver implementations should follow existing code style validated with make lint (fix with make lint-fix), perform static type checking with make ty-pkg-${package_name}, add comprehensive tests, and verify all tests pass with make test-pkg-${package_name} or make test

Files:

  • packages/jumpstarter-driver-ridesx/jumpstarter_driver_ridesx/client.py
**/*.py

📄 CodeRabbit inference engine (.cursor/rules/project-structure.mdc)

Ruff should be used for code formatting and linting, excluding jumpstarter-protocol package

Files:

  • packages/jumpstarter-driver-ridesx/jumpstarter_driver_ridesx/client.py
🧠 Learnings (4)
📚 Learning: 2025-11-05T13:33:24.741Z
Learnt from: mangelajo
Repo: jumpstarter-dev/jumpstarter PR: 735
File: packages/jumpstarter-driver-flashers/jumpstarter_driver_flashers/client.py:476-486
Timestamp: 2025-11-05T13:33:24.741Z
Learning: In packages/jumpstarter-driver-flashers/jumpstarter_driver_flashers/client.py, the FLS flasher download in _flash_with_fls() hardcodes "aarch64-linux" architecture because the flasher always targets ARM devices currently.

Applied to files:

  • packages/jumpstarter-driver-ridesx/jumpstarter_driver_ridesx/client.py
📚 Learning: 2025-11-05T13:31:39.304Z
Learnt from: mangelajo
Repo: jumpstarter-dev/jumpstarter PR: 735
File: packages/jumpstarter-driver-flashers/jumpstarter_driver_flashers/client.py:100-101
Timestamp: 2025-11-05T13:31:39.304Z
Learning: In packages/jumpstarter-driver-flashers/jumpstarter_driver_flashers/client.py, the `flash()` method and its CLI command intentionally have different defaults for `fls_version`: the method defaults to `""` (empty string) while the CLI defaults to `"0.1.5"`. This is by design to provide CLI users with a convenient default while keeping the programmatic API ready for when FLS is included in the flasher images.

Applied to files:

  • packages/jumpstarter-driver-ridesx/jumpstarter_driver_ridesx/client.py
📚 Learning: 2025-03-14T16:05:14.577Z
Learnt from: mangelajo
Repo: jumpstarter-dev/jumpstarter PR: 339
File: packages/jumpstarter-driver-flashers/jumpstarter_driver_flashers/client.py:349-349
Timestamp: 2025-03-14T16:05:14.577Z
Learning: The `_upload_artifact` method in `BaseFlasherClient` class should call `write_from_path` with the calculated filename parameter: `storage.write_from_path(filename, path, operator=operator)` instead of `storage.write_from_path(path, operator=operator)`.

Applied to files:

  • packages/jumpstarter-driver-ridesx/jumpstarter_driver_ridesx/client.py
📚 Learning: 2025-11-27T09:58:41.875Z
Learnt from: CR
Repo: jumpstarter-dev/jumpstarter PR: 0
File: .cursor/rules/creating-new-drivers.mdc:0-0
Timestamp: 2025-11-27T09:58:41.875Z
Learning: Applies to packages/jumpstarter-driver-*/jumpstarter_driver_*/client.py : Driver client CLIs should either implement known classes that provide a CLI interface, or implement their own CLI interface. Use `CompositeClient` from `jumpstarter_driver_composite.client` for composite drivers with child drivers.

Applied to files:

  • packages/jumpstarter-driver-ridesx/jumpstarter_driver_ridesx/client.py
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (11)
  • GitHub Check: Redirect rules - jumpstarter-docs
  • GitHub Check: Header rules - jumpstarter-docs
  • GitHub Check: Pages changed - jumpstarter-docs
  • GitHub Check: build
  • GitHub Check: pytest-matrix (ubuntu-24.04, 3.11)
  • GitHub Check: pytest-matrix (ubuntu-24.04, 3.12)
  • GitHub Check: pytest-matrix (macos-15, 3.12)
  • GitHub Check: pytest-matrix (macos-15, 3.11)
  • GitHub Check: pytest-matrix (ubuntu-24.04, 3.13)
  • GitHub Check: pytest-matrix (macos-15, 3.13)
  • GitHub Check: e2e
🔇 Additional comments (6)
packages/jumpstarter-driver-ridesx/jumpstarter_driver_ridesx/client.py (6)

1-13: LGTM!

The new imports are appropriate for the HTTP(S) download functionality being added.


30-32: LGTM!

The HTTP URL detection logic is straightforward and correct.


57-93: LGTM with a clarification note.

The HTTP(S) download logic correctly handles insecure TLS and falls back to opendal for other schemes. Note that HTTP(S) URLs with an explicit operator will skip the aiohttp path and use opendal instead (line 63). This appears intentional but ensure it aligns with expected behavior.


95-130: LGTM!

The insecure_tls parameter is properly propagated through the flash workflow.


132-171: LGTM!

The insecure_tls parameter is correctly propagated to flash_images.


182-183: LGTM!

Filtering out the generic flash command to provide a custom implementation is appropriate for the RideSX-specific CLI requirements.

async with aiohttp.ClientSession(connector=connector) as session:
async with session.get(url) as response:
response.raise_for_status()
with tempfile.NamedTemporaryFile(delete=False, dir="/var/tmp") as f:
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash

# Find and examine the client.py file in the jumpstarter-driver-ridesx package
find . -path "*/packages/jumpstarter-driver-ridesx/jumpstarter_driver_ridesx/client.py" 2>/dev/null | head -1 | xargs ls -la 2>/dev/null || echo "File path not found, searching by name..."

# Try alternative search
find . -name "client.py" -path "*ridesx*" 2>/dev/null | head -5

Repository: jumpstarter-dev/jumpstarter

Length of output: 265


🏁 Script executed:

#!/bin/bash

# List files in the repository to find the right structure
git ls-files | grep -E "ridesx|client\.py" | head -20

Repository: jumpstarter-dev/jumpstarter

Length of output: 1408


🏁 Script executed:

#!/bin/bash

# Look at the file around line 46
find . -path "*jumpstarter-driver-ridesx*/client.py" -exec cat -n {} + 2>/dev/null | sed -n '40,55p'

Repository: jumpstarter-dev/jumpstarter

Length of output: 884


🏁 Script executed:

#!/bin/bash

# Search for all uses of NamedTemporaryFile in the codebase
rg -n "NamedTemporaryFile" --type=py -B2 -A2

Repository: jumpstarter-dev/jumpstarter

Length of output: 21514


🏁 Script executed:

#!/bin/bash

# First, let's find the actual file
find . -type f -name "client.py" | xargs grep -l "NamedTemporaryFile" 2>/dev/null

Repository: jumpstarter-dev/jumpstarter

Length of output: 281


🏁 Script executed:

#!/bin/bash

# Search for the ridesx client.py file
rg "NamedTemporaryFile" --type py -l

Repository: jumpstarter-dev/jumpstarter

Length of output: 970


🏁 Script executed:

#!/bin/bash
# Find all NamedTemporaryFile usages and their context
rg -n "NamedTemporaryFile" --type=py -B3 -A3 | head -60

Repository: jumpstarter-dev/jumpstarter

Length of output: 5456


🏁 Script executed:

#!/bin/bash
# Specifically look for the file mentioned in the review
if [ -f "packages/jumpstarter-driver-ridesx/jumpstarter_driver_ridesx/client.py" ]; then
  echo "=== File exists, showing context around line 46 ==="
  sed -n '40,55p' "packages/jumpstarter-driver-ridesx/jumpstarter_driver_ridesx/client.py" | cat -n
else
  echo "File not found at expected path"
  find . -name "client.py" -path "*ridesx*" 2>/dev/null
fi

Repository: jumpstarter-dev/jumpstarter

Length of output: 936


🏁 Script executed:

#!/bin/bash
# Check how tempfile is used throughout the codebase
echo "=== All tempfile uses in the codebase ==="
rg "tempfile\." --type=py | head -30

Repository: jumpstarter-dev/jumpstarter

Length of output: 3959


Remove hardcoded /var/tmp directory.

The hardcoded dir="/var/tmp" parameter restricts portability unnecessarily. Python's tempfile module automatically searches through /tmp, /var/tmp, and /usr/tmp when no directory is specified, adapting to each deployment environment. Remove the dir parameter to align with the codebase pattern (all other NamedTemporaryFile calls in the repository omit this) and allow the code to work across containers, Windows, macOS, and restricted environments.

🤖 Prompt for AI Agents
In packages/jumpstarter-driver-ridesx/jumpstarter_driver_ridesx/client.py around
line 46, the call to tempfile.NamedTemporaryFile uses a hardcoded
dir="/var/tmp", which reduces portability; remove the dir parameter so
NamedTemporaryFile uses the system default temp directory (i.e., call
tempfile.NamedTemporaryFile(...) without dir) to match the repository pattern
and allow the code to run correctly across containers, Windows, macOS, and
restricted environments.

@bennyz bennyz requested a review from mangelajo December 23, 2025 08:55
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