Skip to content
This repository was archived by the owner on Jan 23, 2026. It is now read-only.

builroot-based flasher images#535

Merged
mangelajo merged 7 commits intojumpstarter-dev:mainfrom
michalskrivanek:buildroot_flasher
Jun 30, 2025
Merged

builroot-based flasher images#535
mangelajo merged 7 commits intojumpstarter-dev:mainfrom
michalskrivanek:buildroot_flasher

Conversation

@michalskrivanek
Copy link
Contributor

@michalskrivanek michalskrivanek commented Jun 26, 2025

A single config building two FIT images supporting similar-enough boards using either upstream or kernel-automotive kernel. Includes TI J784S4EVM, SK-AM69 and Renesas R-Car S4 Spider and SK.

Summary by CodeRabbit

  • New Features

    • Enhanced support for device tree blob (DTB) variants with customizable boot commands in manifests.
    • Added new manifests, kernel configurations, and scripts for TI J784S4 and Renesas R-Car S4 platforms.
    • Introduced automated FIT image building and kernel replacement scripts for aarch64 devices.
    • Added optional driver configuration parameters for selecting DTB variant and manifest file.
  • Bug Fixes

    • Improved validation and error reporting for DTB variant selection and missing DTB files.
  • Documentation

    • Updated README with new DTB variant and manifest configuration options.
  • Tests

    • Added extensive tests covering boot command retrieval and DTB variant behavior.
  • Chores

    • Updated bundle build scripts to include all YAML manifests and exclude placeholder files.
    • Added udev rules and network scripts for interface setup on Renesas platforms.

@netlify
Copy link

netlify bot commented Jun 26, 2025

Deploy Preview for jumpstarter-docs ready!

Name Link
🔨 Latest commit 3d1f825
🔍 Latest deploy log https://app.netlify.com/projects/jumpstarter-docs/deploys/6862bef10a736400084755d4
😎 Deploy Preview https://deploy-preview-535--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 Jun 26, 2025

## Walkthrough

This update introduces structured support for Device Tree Blob (DTB) variants in the flasher driver and bundle specification. Manifest and driver logic now allow selecting and retrieving DTB-specific boot commands and files. Multiple new test cases, manifests, and build scripts were added to support and verify variant-based flashing and booting for different hardware platforms.

## Changes

| File(s)                                                                                                  | Change Summary                                                                                                                       |
|---------------------------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------|
| bundle.py, client.py, driver.py                                                                         | Refactored DTB handling: introduced `Dtb`/`DtbVariant` models, added bootcmd/file fields, updated method signatures and logic.       |
| driver_test.py, test_bundle.py                                                                           | Added tests for DTB variant boot command retrieval, variant switching, and error handling.                                           |
| oci_bundles/aarch64-itb/automotive.its, buildroot.its                                                  | Added DTS files defining multi-variant FIT images for automotive and buildroot kernels.                                              |
| oci_bundles/aarch64-itb/build_fits.sh, replace_kernel.sh, overlay/etc/network/if-pre-up.d/wait-carrier.sh | Added build automation scripts for FIT images, kernel replacement, and network carrier wait.                                         |
| oci_bundles/aarch64-itb/buildroot_defconfig                                                            | Added Buildroot configuration for aarch64-itb flasher with kernel, initrd, and DTB settings.                                         |
| oci_bundles/aarch64-itb/manifest-renesas.yaml, manifest-ti.yaml, manifest.yaml                           | Added/modified manifests for Renesas and TI platforms with structured DTB variants and boot commands.                                |
| oci_bundles/test/manifest.yaml, ti_j784s4xevm/manifest.yaml                                            | Updated manifest DTB variants to structured mapping with `file` and `bootcmd` keys.                                                  |
| build_bundle.sh                                                                                        | Enhanced script to include all YAML manifests and exclude `.gitkeep` files in OCI bundle build.                                      |
| README.md                                                                                             | Documented new `variant`, `manifest`, and `default_target` configuration parameters.                                                 |
| jumpstarter_cli/j.py                                                                                  | Added Rich traceback handler installation for improved error output during CLI execution.                                            |

## Sequence Diagram(s)

```mermaid
sequenceDiagram
    participant User
    participant Driver
    participant BundleManifest

    User->>Driver: use_dtb_variant(variant_name)
    Driver->>BundleManifest: get_dtb_file(variant_name)
    BundleManifest-->>Driver: DTB file path or error

    User->>Driver: get_bootcmd()
    Driver->>BundleManifest: get_boot_cmd(variant_name)
    BundleManifest-->>Driver: boot command (variant-specific or default)
    Driver-->>User: boot command

Possibly related PRs

  • jumpstarter-dev/jumpstarter#339: Introduced the initial flasher driver and bundle classes, which are now extended with DTB variant and boot command support in this PR.

Poem

In the meadow of code, a rabbit did dash,
With DTB variants and boot commands to stash.
Manifests now smarter, drivers more wise—
Each board gets a boot, with a tailored surprise!
Scripts build and test, all bundles anew,
This flasher hops farther, for hardware and you!
🐇✨


<!-- walkthrough_end -->


---

<details>
<summary>📜 Recent review details</summary>

**Configuration used: CodeRabbit UI**
**Review profile: CHILL**
**Plan: Pro**


<details>
<summary>📥 Commits</summary>

Reviewing files that changed from the base of the PR and between ec96675702039fa9304b70a8a4f54922a7f73e98 and 3d1f825cec91d7a3ac324d3267956ae45ed5e405.

</details>

<details>
<summary>⛔ Files ignored due to path filters (1)</summary>

* `uv.lock` is excluded by `!**/*.lock`

</details>

<details>
<summary>📒 Files selected for processing (4)</summary>

* `packages/jumpstarter-cli/jumpstarter_cli/j.py` (2 hunks)
* `packages/jumpstarter-driver-flashers/README.md` (1 hunks)
* `packages/jumpstarter-driver-flashers/jumpstarter_driver_flashers/client.py` (2 hunks)
* `packages/jumpstarter-driver-flashers/jumpstarter_driver_flashers/driver.py` (7 hunks)

</details>

<details>
<summary>🚧 Files skipped from review as they are similar to previous changes (3)</summary>

* packages/jumpstarter-cli/jumpstarter_cli/j.py
* packages/jumpstarter-driver-flashers/README.md
* packages/jumpstarter-driver-flashers/jumpstarter_driver_flashers/client.py

</details>

<details>
<summary>🧰 Additional context used</summary>

<details>
<summary>🧠 Learnings (1)</summary>

<details>
<summary>packages/jumpstarter-driver-flashers/jumpstarter_driver_flashers/driver.py (2)</summary>

Learnt from: bennyz
PR: jumpstarter-dev/jumpstarter#241
File: packages/jumpstarter-driver-tftp/jumpstarter_driver_tftp/client.py:52-60
Timestamp: 2025-01-29T11:52:43.554Z
Learning: The TFTP driver (packages/jumpstarter-driver-tftp/jumpstarter_driver_tftp/driver.py) handles all low-level concerns like path validation, error handling, and checksum computation. The client (packages/jumpstarter-driver-tftp/jumpstarter_driver_tftp/client.py) should remain simple as it delegates these responsibilities to the driver.


Learnt from: bennyz
PR: jumpstarter-dev/jumpstarter#267
File: packages/jumpstarter-driver-tftp/jumpstarter_driver_tftp/driver.py:32-40
Timestamp: 2025-02-08T16:08:34.616Z
Learning: In the TFTP driver (jumpstarter_driver_tftp), the TFTP server component is read-only, while file management operations (upload, delete) are handled through the driver's client interface, not through the TFTP protocol itself.


</details>

</details><details>
<summary>🧬 Code Graph Analysis (1)</summary>

<details>
<summary>packages/jumpstarter-driver-flashers/jumpstarter_driver_flashers/driver.py (3)</summary><blockquote>

<details>
<summary>packages/jumpstarter-driver-flashers/jumpstarter_driver_flashers/client.py (1)</summary>

* `manifest` (462-469)

</details>
<details>
<summary>packages/jumpstarter-driver-flashers/jumpstarter_driver_flashers/bundle.py (4)</summary>

* `get_initram_file` (95-98)
* `get_dtb_file` (57-70)
* `FlasherBundleManifestV1Alpha1` (46-114)
* `get_boot_cmd` (72-87)

</details>
<details>
<summary>packages/jumpstarter-driver-opendal/jumpstarter_driver_opendal/driver.py (4)</summary>

* `copy_exporter_file` (193-203)
* `open` (41-52)
* `read` (260-260)
* `read` (293-297)

</details>

</blockquote></details>

</details><details>
<summary>🪛 Pylint (3.3.7)</summary>

<details>
<summary>packages/jumpstarter-driver-flashers/jumpstarter_driver_flashers/driver.py</summary>

[refactor] 196-199: Unnecessary "else" after "return", remove the "else" and de-indent the code inside it

(R1705)

</details>

</details>

</details>

<details>
<summary>⏰ Context from checks skipped due to timeout of 90000ms (6)</summary>

* GitHub Check: e2e
* GitHub Check: pytest-matrix (ubuntu-24.04, 3.12)
* GitHub Check: pytest-matrix (macos-15, 3.11)
* GitHub Check: pytest-matrix (ubuntu-24.04, 3.11)
* GitHub Check: pytest-matrix (macos-15, 3.13)
* GitHub Check: pytest-matrix (ubuntu-24.04, 3.13)

</details>

<details>
<summary>🔇 Additional comments (7)</summary><blockquote>

<details>
<summary>packages/jumpstarter-driver-flashers/jumpstarter_driver_flashers/driver.py (7)</summary>

`20-22`: **LGTM! Well-structured configuration fields added.**

The new public fields provide clean configuration options for variant selection, manifest filename, and default target specification with appropriate defaults and type hints.

---

`67-70`: **LGTM! Simple and consistent getter method.**

The method follows the established pattern of other getter methods in the class.

---

`89-99`: **LGTM! Improved conditional file handling with variant support.**

The changes properly utilize the manifest's methods to conditionally handle initram and DTB files, with appropriate variant support for DTB selection.

---

`110-119`: **LGTM! Enhanced error messaging with available variants.**

The improved error handling provides helpful context by listing available variants when validation fails, making debugging easier for users.

---

`162-163`: **LGTM! Good defensive programming practice.**

Adding the None check prevents potential downstream errors and provides clear error messaging.

---

`170-174`: **LGTM! Consistent use of configurable manifest filename.**

Using `self.manifest` instead of hardcoded filenames makes the implementation more flexible and consistent.

---

`219-223`: **LGTM! Clean method for retrieving boot commands with variant support.**

The method properly delegates to the manifest's `get_boot_cmd` method with variant parameter.

</details>

</blockquote></details>

</details>
<!-- internal state start -->


<!-- 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 -->

<!-- internal state end -->
<!-- finishing_touch_checkbox_start -->

<details open="true">
<summary>✨ Finishing Touches</summary>

- [ ] <!-- {"checkboxId": "7962f53c-55bc-4827-bfbf-6a18da830691"} --> 📝 Generate Docstrings

</details>

<!-- finishing_touch_checkbox_end -->
<!-- tips_start -->

---

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.

<details>
<summary>❤️ Share</summary>

- [X](https://twitter.com/intent/tweet?text=I%20just%20used%20%40coderabbitai%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20the%20proprietary%20code.%20Check%20it%20out%3A&url=https%3A//coderabbit.ai)
- [Mastodon](https://mastodon.social/share?text=I%20just%20used%20%40coderabbitai%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20the%20proprietary%20code.%20Check%20it%20out%3A%20https%3A%2F%2Fcoderabbit.ai)
- [Reddit](https://www.reddit.com/submit?title=Great%20tool%20for%20code%20review%20-%20CodeRabbit&text=I%20just%20used%20CodeRabbit%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20proprietary%20code.%20Check%20it%20out%3A%20https%3A//coderabbit.ai)
- [LinkedIn](https://www.linkedin.com/sharing/share-offsite/?url=https%3A%2F%2Fcoderabbit.ai&mini=true&title=Great%20tool%20for%20code%20review%20-%20CodeRabbit&summary=I%20just%20used%20CodeRabbit%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20proprietary%20code)

</details>

<details>
<summary>🪧 Tips</summary>

### Chat

There are 3 ways to chat with [CodeRabbit](https://coderabbit.ai?utm_source=oss&utm_medium=github&utm_campaign=jumpstarter-dev/jumpstarter&utm_content=535):

- Review comments: Directly reply to a review comment made by CodeRabbit. Example:
  - `I pushed a fix in commit <commit_id>, please review it.`
  - `Explain this complex logic.`
  - `Open a follow-up GitHub issue for this discussion.`
- Files and specific lines of code (under the "Files changed" tab): Tag `@coderabbitai` in a new review comment at the desired location with your query. Examples:
  - `@coderabbitai explain this code block.`
  -	`@coderabbitai modularize this function.`
- PR comments: Tag `@coderabbitai` in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
  - `@coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.`
  - `@coderabbitai read src/utils.ts and explain its main purpose.`
  - `@coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.`
  - `@coderabbitai help me debug CodeRabbit configuration file.`

### Support

Need help? Create a ticket on our [support page](https://www.coderabbit.ai/contact-us/support) for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

### CodeRabbit Commands (Invoked using PR comments)

- `@coderabbitai pause` to pause the reviews on a PR.
- `@coderabbitai resume` to resume the paused reviews.
- `@coderabbitai review` to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
- `@coderabbitai full review` to do a full review from scratch and review all the files again.
- `@coderabbitai summary` to regenerate the summary of the PR.
- `@coderabbitai generate docstrings` to [generate docstrings](https://docs.coderabbit.ai/finishing-touches/docstrings) for this PR.
- `@coderabbitai generate sequence diagram` to generate a sequence diagram of the changes in this PR.
- `@coderabbitai resolve` resolve all the CodeRabbit review comments.
- `@coderabbitai configuration` to show the current CodeRabbit configuration for the repository.
- `@coderabbitai help` to get help.

### Other keywords and placeholders

- Add `@coderabbitai ignore` anywhere in the PR description to prevent this PR from being reviewed.
- Add `@coderabbitai summary` to generate the high-level summary at a specific location in the PR description.
- Add `@coderabbitai` anywhere in the PR title to generate the title automatically.

### CodeRabbit Configuration File (`.coderabbit.yaml`)

- You can programmatically configure CodeRabbit by adding a `.coderabbit.yaml` file to the root of your repository.
- Please see the [configuration documentation](https://docs.coderabbit.ai/guides/configure-coderabbit) for more information.
- If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: `# yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json`

### Documentation and Community

- Visit our [Documentation](https://docs.coderabbit.ai) for detailed information on how to use CodeRabbit.
- Join our [Discord Community](http://discord.gg/coderabbit) to get help, request features, and share feedback.
- Follow us on [X/Twitter](https://twitter.com/coderabbitai) for updates and announcements.

</details>

<!-- tips_end -->

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: 6

🧹 Nitpick comments (6)
packages/jumpstarter-driver-flashers/oci_bundles/buildroot/buildroot_defconfig (2)

7-8: Blank root password – reconsider for production images

BR2_TARGET_GENERIC_ROOT_PASSWD="" leaves the root account without a password.
OK for disposable flashers, but if any board ever ships with this image untouched, it’s an immediate privilege-escalation vector (UART, SSH after user installs it, etc.).

If you want password-less console for manufacturing only, consider:

-BR2_TARGET_GENERIC_ROOT_PASSWD=""
+# Root remains locked; an overlay or first-boot script can set a password if required
+# BR2_TARGET_GENERIC_ROOT_PASSWD is not set

…and rely on a provisioning step to unlock it.


19-20: Non-canonical kconfig syntax

BR2_PACKAGE_DROPBEAR=n works, but Buildroot convention (and what make savedefconfig emits) is:

# BR2_PACKAGE_DROPBEAR is not set

Sticking to the canonical form avoids noisy diffs when someone later runs savedefconfig.

packages/jumpstarter-driver-flashers/oci_bundles/buildroot/overlay/etc/network/if-pre-up.d/wait-carrier.sh (1)

5-16: Robustness & POSIX shell nits

  1. ip link set ${IFACE} up – quote ${IFACE} to survive funky interface names.
  2. $(cat …/carrier) – if the file disappears/misreports you get endless cat: ...: No such file spam.
  3. The arithmetic decrement inside : is a Bashism; BusyBox sh supports it, but plain POSIX dash doesn’t.

Minimal, strictly‐POSIX tweak:

-ip link set ${IFACE} up
+ip link set "${IFACE}" up
 ...
-        if [ "$(cat /sys/class/net/${IFACE}/carrier)" = "1" ]; then
+        if [ -r "/sys/class/net/${IFACE}/carrier" ] &&
+           [ "$(cat "/sys/class/net/${IFACE}/carrier")" = 1 ]; then
 ...
-        : $((IF_WAIT_DELAY -= 1))
+        IF_WAIT_DELAY=$((IF_WAIT_DELAY-1))
packages/jumpstarter-driver-flashers/oci_bundles/buildroot/automotive.its (1)

22-24: Typo in DTB description

"DTB Renesas 8779f0-spider" is missing the initial r. Cosmetic, but this string shows up in U-Boot logs.

-            description = "DTB Renesas 8779f0-spider";
+            description = "DTB Renesas r8a779f0-spider";
packages/jumpstarter-driver-flashers/oci_bundles/buildroot/build_fits.sh (1)

10-11: ShellCheck SC2164 – harmless here

The subshell ( cd /buildroot; make … ) ignores a failed cd. With set -e added earlier, use an explicit guard or cd /buildroot || exit.

packages/jumpstarter-driver-flashers/oci_bundles/buildroot/buildroot.its (1)

15-17: Kernel load/entry address hard-coded

0x80000000 is fine for many TI boards but double-check the AM69 SPL/U-Boot expects that. Mismatched addresses cause silent hangs.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 629e3e1 and 3cd0adc.

📒 Files selected for processing (8)
  • packages/jumpstarter-driver-flashers/oci_bundles/buildroot/automotive.its (1 hunks)
  • packages/jumpstarter-driver-flashers/oci_bundles/buildroot/build_fits.sh (1 hunks)
  • packages/jumpstarter-driver-flashers/oci_bundles/buildroot/buildroot.its (1 hunks)
  • packages/jumpstarter-driver-flashers/oci_bundles/buildroot/buildroot_defconfig (1 hunks)
  • packages/jumpstarter-driver-flashers/oci_bundles/buildroot/manifest-automotive.yaml (1 hunks)
  • packages/jumpstarter-driver-flashers/oci_bundles/buildroot/manifest-buildroot.yaml (1 hunks)
  • packages/jumpstarter-driver-flashers/oci_bundles/buildroot/overlay/etc/network/if-pre-up.d/wait-carrier.sh (1 hunks)
  • packages/jumpstarter-driver-flashers/oci_bundles/buildroot/replace_kernel.sh (1 hunks)
🧰 Additional context used
🪛 Shellcheck (0.10.0)
packages/jumpstarter-driver-flashers/oci_bundles/buildroot/build_fits.sh

[warning] 10-10: Use 'cd ... || exit' or 'cd ... || return' in case cd fails.

(SC2164)

packages/jumpstarter-driver-flashers/oci_bundles/buildroot/replace_kernel.sh

[warning] 19-19: Use 'pushd ... || exit' or 'pushd ... || return' in case pushd fails.

(SC2164)


[warning] 24-24: Quote to prevent word splitting/globbing, or split robustly with mapfile or read -a.

(SC2206)


[warning] 25-25: Quote to prevent word splitting/globbing, or split robustly with mapfile or read -a.

(SC2206)


[warning] 26-26: Quote to prevent word splitting/globbing, or split robustly with mapfile or read -a.

(SC2206)


[error] 31-31: Double quote array expansions to avoid re-splitting elements.

(SC2068)


[error] 36-36: Double quote array expansions to avoid re-splitting elements.

(SC2068)


[error] 46-46: Double quote array expansions to avoid re-splitting elements.

(SC2068)


[warning] 50-50: Use 'popd ... || exit' or 'popd ... || return' in case popd fails.

(SC2164)

⏰ Context from checks skipped due to timeout of 90000ms (7)
  • GitHub Check: pytest-matrix (macos-15, 3.11)
  • GitHub Check: pytest-matrix (macos-15, 3.12)
  • GitHub Check: pytest-matrix (ubuntu-24.04, 3.13)
  • GitHub Check: pytest-matrix (macos-15, 3.13)
  • GitHub Check: pytest-matrix (ubuntu-24.04, 3.11)
  • GitHub Check: pytest-matrix (ubuntu-24.04, 3.12)
  • GitHub Check: e2e
🔇 Additional comments (4)
packages/jumpstarter-driver-flashers/oci_bundles/buildroot/automotive.its (1)

10-17: Absolute paths make mkimage brittle

/incbin/("/kernel-automotive/vmlinuz") assumes the build is run from filesystem root with that directory present.
Prefer a relative path so the build can be relocated:

-            data = /incbin/("/kernel-automotive/vmlinuz");
+            data = /incbin/("./kernel-automotive/vmlinuz");

Same for the DTB and ramdisk paths below.

packages/jumpstarter-driver-flashers/oci_bundles/buildroot/buildroot.its (1)

32-46: DTB path may be wrong after Buildroot install

Buildroot copies DTBs into output/images/ without the ti/ subdirectory, so:

/buildroot/output/images/k3-j784s4-evm.dtb
/buildroot/output/images/ti/k3-j784s4-evm.dtb

Please verify on a fresh build; if the files land inside a ti/ folder, update the ITS accordingly for both DTBs.

packages/jumpstarter-driver-flashers/oci_bundles/buildroot/manifest-automotive.yaml (1)

1-20: Manifest looks syntactically correct – please just run yamllint once.

Nothing blocking, but running a linter will catch accidental indent / quoting issues before they land.

packages/jumpstarter-driver-flashers/oci_bundles/buildroot/replace_kernel.sh (1)

52-58: Module install assumes all objects are .ko.zst; CentOS 9 Automotive kernels ship plain .ko.

If a module is not compressed with zstd, zstd -d … will fail and the script aborts.
Consider detecting the actual extension:

mod_path="/kernel-automotive${mod}"
if [[ -f "${mod_path}.zst" ]]; then
    zstd -d "${mod_path}.zst" -o "$ODIR$mod"
else
    cp "${mod_path}" "$ODIR$mod"
fi

@michalskrivanek
Copy link
Contributor Author

michalskrivanek commented Jun 26, 2025

[WIP - still needs the corresponding API changes for selecting the right config]

@bennyz @mangelajo this is a combination of #510 and #507, using the single config building both kernel+initrd(6.14 kernel for TI) and kernel-automotive+initrd for S4

The configs are fully reused and the time to build is less as well as the second pass with kernel-automotive is a trivial repackage only (though note the initrds are slightly different due to the extra kernel-automotive modules)
If we go this way we can drop the TI and S4 specific bundles (and hopefully save ourselves from introducing new ones)

This produces two 70MB FITs, the complete bundle would be 140MB. It's not too bad, so I wonder if it's better to split this into two bundles or keep it all together with a single manifest and leave it up to the user to pick one or the other.

@michalskrivanek michalskrivanek force-pushed the buildroot_flasher branch 2 times, most recently from 8aed798 to 5704735 Compare June 26, 2025 08:47
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: 2

♻️ Duplicate comments (1)
packages/jumpstarter-driver-flashers/oci_bundles/buildroot/replace_kernel.sh (1)

46-48: Unquoted array expansion – issue already flagged earlier
for mod in ${KMOD[@]}; do re-splits elements and was pointed out in the previous round. Please quote the expansion:

-for mod in ${KMOD[@]}; do
+for mod in "${KMOD[@]}"; do
🧹 Nitpick comments (2)
packages/jumpstarter-driver-flashers/oci_bundles/buildroot/replace_kernel.sh (2)

53-57: Missing quotes around user-supplied path
$ODIR may legally contain spaces or glob chars. Quote every occurrence to avoid surprises.

-mkdir -p $ODIR/lib/modules $ODIR/etc/init.d || exit 1
+mkdir -p "$ODIR/lib/modules" "$ODIR/etc/init.d" || exit 1-zstd -d "/kernel-automotive$mod.zst" -o "$ODIR$mod"
+zstd -d "/kernel-automotive$mod.zst" -o "$ODIR$mod"

1-2: Add set -euo pipefail for safer scripting
Early exit on error, unset vars, and failed pipelines prevents half-baked images from being produced.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 8aed798 and 5704735.

📒 Files selected for processing (8)
  • packages/jumpstarter-driver-flashers/oci_bundles/buildroot/automotive.its (1 hunks)
  • packages/jumpstarter-driver-flashers/oci_bundles/buildroot/build_fits.sh (1 hunks)
  • packages/jumpstarter-driver-flashers/oci_bundles/buildroot/buildroot.its (1 hunks)
  • packages/jumpstarter-driver-flashers/oci_bundles/buildroot/buildroot_defconfig (1 hunks)
  • packages/jumpstarter-driver-flashers/oci_bundles/buildroot/manifest-automotive.yaml (1 hunks)
  • packages/jumpstarter-driver-flashers/oci_bundles/buildroot/manifest-buildroot.yaml (1 hunks)
  • packages/jumpstarter-driver-flashers/oci_bundles/buildroot/overlay/etc/network/if-pre-up.d/wait-carrier.sh (1 hunks)
  • packages/jumpstarter-driver-flashers/oci_bundles/buildroot/replace_kernel.sh (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (7)
  • packages/jumpstarter-driver-flashers/oci_bundles/buildroot/overlay/etc/network/if-pre-up.d/wait-carrier.sh
  • packages/jumpstarter-driver-flashers/oci_bundles/buildroot/automotive.its
  • packages/jumpstarter-driver-flashers/oci_bundles/buildroot/manifest-automotive.yaml
  • packages/jumpstarter-driver-flashers/oci_bundles/buildroot/build_fits.sh
  • packages/jumpstarter-driver-flashers/oci_bundles/buildroot/buildroot_defconfig
  • packages/jumpstarter-driver-flashers/oci_bundles/buildroot/buildroot.its
  • packages/jumpstarter-driver-flashers/oci_bundles/buildroot/manifest-buildroot.yaml
🧰 Additional context used
🪛 Shellcheck (0.10.0)
packages/jumpstarter-driver-flashers/oci_bundles/buildroot/replace_kernel.sh

[warning] 19-19: Use 'pushd ... || exit' or 'pushd ... || return' in case pushd fails.

(SC2164)


[warning] 24-24: Quote to prevent word splitting/globbing, or split robustly with mapfile or read -a.

(SC2206)


[warning] 25-25: Quote to prevent word splitting/globbing, or split robustly with mapfile or read -a.

(SC2206)


[warning] 26-26: Quote to prevent word splitting/globbing, or split robustly with mapfile or read -a.

(SC2206)


[error] 46-46: Double quote array expansions to avoid re-splitting elements.

(SC2068)


[warning] 50-50: Use 'popd ... || exit' or 'popd ... || return' in case popd fails.

(SC2164)

⏰ Context from checks skipped due to timeout of 90000ms (6)
  • GitHub Check: pytest-matrix (ubuntu-24.04, 3.12)
  • GitHub Check: e2e
  • GitHub Check: pytest-matrix (ubuntu-24.04, 3.13)
  • GitHub Check: pytest-matrix (macos-15, 3.11)
  • GitHub Check: pytest-matrix (macos-15, 3.12)
  • GitHub Check: pytest-matrix (ubuntu-24.04, 3.11)
🔇 Additional comments (1)
packages/jumpstarter-driver-flashers/oci_bundles/buildroot/replace_kernel.sh (1)

41-41: unzboot utility may be a typo / non-standard
unzboot is not part of common base images (unlike zstd, xz, gzip). If this is a custom tool ensure it’s available in the Buildroot host tools; otherwise the script will fail at runtime.

#!/bin/bash
command -v unzboot || echo "unzboot missing in PATH"

Comment on lines +19 to +20
pushd /kernel-automotive

Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

pushd / popd need failure guards
If the directory change fails the script continues in an unpredictable CWD. Shell-idiom is to bail out:

-pushd /kernel-automotive
+pushd /kernel-automotive || exit 1-popd
+popd || exit 1

Also applies to: 50-50

🧰 Tools
🪛 Shellcheck (0.10.0)

[warning] 19-19: Use 'pushd ... || exit' or 'pushd ... || return' in case pushd fails.

(SC2164)

🤖 Prompt for AI Agents
In packages/jumpstarter-driver-flashers/oci_bundles/buildroot/replace_kernel.sh
at lines 19-20 and 50-51, the pushd commands lack failure checks, which can
cause the script to continue in an unexpected directory if the pushd fails. Add
a conditional check after each pushd to verify it succeeded, and if not, exit
the script immediately with a non-zero status to prevent unpredictable behavior.

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 (2)
packages/jumpstarter-driver-flashers/oci_bundles/buildroot/replace_kernel.sh (2)

18-20: pushd lacks failure guard – identical to earlier feedback
If /kernel-automotive cannot be entered, the script will continue in an unexpected CWD.

-pushd /kernel-automotive
+pushd /kernel-automotive || exit 1

50-50: popd should also be guarded – symmetry with the pushd fix.

-popd
+popd || exit 1
🧹 Nitpick comments (2)
packages/jumpstarter-driver-flashers/oci_bundles/buildroot/replace_kernel.sh (2)

46-48: Unquoted array expansion – potential word-splitting (SC2068)

-for mod in ${KMOD[@]}; do
+for mod in "${KMOD[@]}"; do

Quoting is cheap, avoids latent bugs, and silences ShellCheck.


52-57: Path handling inside the overlay is brittle – quote $ODIR everywhere

Several commands concatenate $ODIR without quoting, breaking paths with spaces:

-mkdir -p $ODIR/lib/modules $ODIR/etc/init.d || exit 1
+mkdir -p "$ODIR"/lib/modules "$ODIR"/etc/init.d || exit 1

-mkdir -p "$ODIR$(dirname $mod)"
-zstd -d "/kernel-automotive$mod.zst" -o "$ODIR$mod"
+mkdir -p "$ODIR$(dirname "$mod")"
+zstd -d "/kernel-automotive$mod.zst" -o "$ODIR$mod"
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 5704735 and a392186.

📒 Files selected for processing (8)
  • packages/jumpstarter-driver-flashers/oci_bundles/buildroot/automotive.its (1 hunks)
  • packages/jumpstarter-driver-flashers/oci_bundles/buildroot/build_fits.sh (1 hunks)
  • packages/jumpstarter-driver-flashers/oci_bundles/buildroot/buildroot.its (1 hunks)
  • packages/jumpstarter-driver-flashers/oci_bundles/buildroot/buildroot_defconfig (1 hunks)
  • packages/jumpstarter-driver-flashers/oci_bundles/buildroot/manifest-automotive.yaml (1 hunks)
  • packages/jumpstarter-driver-flashers/oci_bundles/buildroot/manifest-buildroot.yaml (1 hunks)
  • packages/jumpstarter-driver-flashers/oci_bundles/buildroot/overlay/etc/network/if-pre-up.d/wait-carrier.sh (1 hunks)
  • packages/jumpstarter-driver-flashers/oci_bundles/buildroot/replace_kernel.sh (1 hunks)
✅ Files skipped from review due to trivial changes (1)
  • packages/jumpstarter-driver-flashers/oci_bundles/buildroot/manifest-automotive.yaml
🚧 Files skipped from review as they are similar to previous changes (6)
  • packages/jumpstarter-driver-flashers/oci_bundles/buildroot/overlay/etc/network/if-pre-up.d/wait-carrier.sh
  • packages/jumpstarter-driver-flashers/oci_bundles/buildroot/build_fits.sh
  • packages/jumpstarter-driver-flashers/oci_bundles/buildroot/automotive.its
  • packages/jumpstarter-driver-flashers/oci_bundles/buildroot/buildroot.its
  • packages/jumpstarter-driver-flashers/oci_bundles/buildroot/buildroot_defconfig
  • packages/jumpstarter-driver-flashers/oci_bundles/buildroot/manifest-buildroot.yaml
🧰 Additional context used
🪛 Shellcheck (0.10.0)
packages/jumpstarter-driver-flashers/oci_bundles/buildroot/replace_kernel.sh

[warning] 19-19: Use 'pushd ... || exit' or 'pushd ... || return' in case pushd fails.

(SC2164)


[warning] 24-24: Quote to prevent word splitting/globbing, or split robustly with mapfile or read -a.

(SC2206)


[warning] 25-25: Quote to prevent word splitting/globbing, or split robustly with mapfile or read -a.

(SC2206)


[warning] 26-26: Quote to prevent word splitting/globbing, or split robustly with mapfile or read -a.

(SC2206)


[error] 46-46: Double quote array expansions to avoid re-splitting elements.

(SC2068)


[warning] 50-50: Use 'popd ... || exit' or 'popd ... || return' in case popd fails.

(SC2164)

⏰ Context from checks skipped due to timeout of 90000ms (7)
  • GitHub Check: pytest-matrix (macos-15, 3.11)
  • GitHub Check: pytest-matrix (ubuntu-24.04, 3.11)
  • GitHub Check: pytest-matrix (macos-15, 3.13)
  • GitHub Check: pytest-matrix (macos-15, 3.12)
  • GitHub Check: pytest-matrix (ubuntu-24.04, 3.13)
  • GitHub Check: pytest-matrix (ubuntu-24.04, 3.12)
  • GitHub Check: e2e

Comment on lines +16 to +17
[ $# -ne 1 ] && { echo "$0 [target_overlay_dir]"; exit 1; }
ODIR=$1
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Usage guard is correct now but message is misleading & $1 should be quoted

[ $# -ne 1 ] correctly enforces “exactly one argument”.
However:

  1. The help text should follow conventional Usage: … wording to avoid confusion.
  2. $1 is later assigned un-quoted (ODIR=$1). If the overlay path contains spaces the script will break.
-if [ $# -ne 1 ]; then
-    echo "$0 [target_overlay_dir]"
+if [ "$#" -ne 1 ]; then
+    echo "Usage: $0 <target_overlay_dir>"
     exit 1
 fi
-ODIR=$1
+ODIR="$1"

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In packages/jumpstarter-driver-flashers/oci_bundles/buildroot/replace_kernel.sh
at lines 16-17, update the usage message to start with "Usage:" for clarity and
quote the variable assignment by changing ODIR=$1 to ODIR="$1" to handle paths
with spaces correctly.

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: 6

🧹 Nitpick comments (7)
packages/jumpstarter-driver-flashers/oci_bundles/aarch64-itb/build_fits.sh (2)

4-4: Improve package installation readability and add error handling.

The package installation command is very long and difficult to read. Consider breaking it into multiple lines or using a package list.

-dnf install --setopt=install_weak_deps=false -y git make gcc gcc-c++ which file diffutils wget cpio rsync bc lzop zip patch perl tar qemu-system-aarch64 qemu-img unzboot uboot-tools kmod awk
+# Install build dependencies
+PACKAGES=(
+    git make gcc gcc-c++ which file diffutils wget cpio rsync bc lzop zip
+    patch perl tar qemu-system-aarch64 qemu-img unzboot uboot-tools kmod awk
+)
+dnf install --setopt=install_weak_deps=false -y "${PACKAGES[@]}"

6-6: Consider parameterizing the buildroot version and adding cleanup.

The buildroot version is hard-coded. Consider making it configurable and adding cleanup on failure.

-git clone --depth 1 --branch 2025.05  https://github.com/buildroot/buildroot /buildroot
+BUILDROOT_VERSION=${BUILDROOT_VERSION:-2025.05}
+git clone --depth 1 --branch "$BUILDROOT_VERSION" https://github.com/buildroot/buildroot /buildroot
+
+# Cleanup function
+cleanup() {
+    rm -rf /buildroot
+}
+trap cleanup EXIT
packages/jumpstarter-driver-flashers/jumpstarter_driver_flashers/driver_test.py (1)

137-143: Test focuses on the wrong method.

This test is named test_drivers_flashers_get_bootcmd_invalid_variant but only tests use_dtb_variant. Consider adding an actual test for get_bootcmd with an invalid variant after setting it.

 def test_drivers_flashers_get_bootcmd_invalid_variant(complete_flasher):
     """Test that get_bootcmd raises DriverInvalidArgument for invalid DTB variant"""
     with serve(complete_flasher) as client:
-        # Set an invalid variant
+        # Try to set an invalid variant
         with pytest.raises(DriverInvalidArgument):
             client.call("use_dtb_variant", "noexists")
+        
+        # Additionally, if a test manifest had an inconsistent state where
+        # variant is set but not in manifest, test get_bootcmd would fail
packages/jumpstarter-driver-flashers/jumpstarter_driver_flashers/bundle.py (3)

16-16: Add blank line before class definition.

PEP 8 requires two blank lines before class definitions.

     file: None | str = None

+
 class Dtb(BaseModel):

65-71: Simplify control flow by removing unnecessary else.

The else block is redundant after a return statement.

         variant_struct = self.spec.dtb.variants.get(variant)
         if variant_struct:
             return variant_struct.file
-        else:
-            raise ValueError(f"DTB variant {variant} not found in the manifest.")
+        raise ValueError(f"DTB variant {variant} not found in the manifest.")

80-87: Simplify nested control flow.

Remove unnecessary else blocks for cleaner code.

         if variant_struct:
             # If variant has a custom bootcmd, use it; otherwise fall back to default
-            if variant_struct.bootcmd:
-                return variant_struct.bootcmd
-            else:
-                return self.spec.bootcmd
-        else:
-            raise ValueError(f"DTB variant {variant} not found in the manifest.")
+            return variant_struct.bootcmd if variant_struct.bootcmd else self.spec.bootcmd
+        raise ValueError(f"DTB variant {variant} not found in the manifest.")
packages/jumpstarter-driver-flashers/jumpstarter_driver_flashers/driver.py (1)

182-189: Consider returning None instead of empty string for consistency.

Other filename methods (e.g., get_initram_filename) return None when the file doesn't exist. Returning an empty string here breaks consistency.

     async def get_dtb_filename(self) -> str:
         """Return the dtb filename"""
         manifest = await self.get_flasher_manifest()
         dtb_file = manifest.get_dtb_file(self.variant)
         if dtb_file:
-            return Path(dtb_file).name
-        return ""
+            return Path(dtb_file).name  
+        return None

Note: This change would require updating the return type annotation to str | None.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between a392186 and 7ae7c05.

📒 Files selected for processing (15)
  • packages/jumpstarter-driver-flashers/jumpstarter_driver_flashers/bundle.py (4 hunks)
  • packages/jumpstarter-driver-flashers/jumpstarter_driver_flashers/client.py (1 hunks)
  • packages/jumpstarter-driver-flashers/jumpstarter_driver_flashers/driver.py (6 hunks)
  • packages/jumpstarter-driver-flashers/jumpstarter_driver_flashers/driver_test.py (3 hunks)
  • packages/jumpstarter-driver-flashers/jumpstarter_driver_flashers/test_bundle.py (2 hunks)
  • packages/jumpstarter-driver-flashers/oci_bundles/aarch64-itb/automotive.its (1 hunks)
  • packages/jumpstarter-driver-flashers/oci_bundles/aarch64-itb/build_fits.sh (1 hunks)
  • packages/jumpstarter-driver-flashers/oci_bundles/aarch64-itb/buildroot.its (1 hunks)
  • packages/jumpstarter-driver-flashers/oci_bundles/aarch64-itb/buildroot_defconfig (1 hunks)
  • packages/jumpstarter-driver-flashers/oci_bundles/aarch64-itb/manifest-automotive.yaml (1 hunks)
  • packages/jumpstarter-driver-flashers/oci_bundles/aarch64-itb/manifest-buildroot.yaml (1 hunks)
  • packages/jumpstarter-driver-flashers/oci_bundles/aarch64-itb/overlay/etc/network/if-pre-up.d/wait-carrier.sh (1 hunks)
  • packages/jumpstarter-driver-flashers/oci_bundles/aarch64-itb/replace_kernel.sh (1 hunks)
  • packages/jumpstarter-driver-flashers/oci_bundles/test/manifest.yaml (1 hunks)
  • packages/jumpstarter-driver-flashers/oci_bundles/ti_j784s4xevm/manifest.yaml (1 hunks)
✅ Files skipped from review due to trivial changes (5)
  • packages/jumpstarter-driver-flashers/oci_bundles/ti_j784s4xevm/manifest.yaml
  • packages/jumpstarter-driver-flashers/oci_bundles/aarch64-itb/overlay/etc/network/if-pre-up.d/wait-carrier.sh
  • packages/jumpstarter-driver-flashers/oci_bundles/aarch64-itb/buildroot.its
  • packages/jumpstarter-driver-flashers/oci_bundles/aarch64-itb/buildroot_defconfig
  • packages/jumpstarter-driver-flashers/oci_bundles/aarch64-itb/automotive.its
🧰 Additional context used
🧠 Learnings (3)
packages/jumpstarter-driver-flashers/jumpstarter_driver_flashers/client.py (2)
Learnt from: bennyz
PR: jumpstarter-dev/jumpstarter#241
File: packages/jumpstarter-driver-tftp/jumpstarter_driver_tftp/client.py:52-60
Timestamp: 2025-01-29T11:52:43.554Z
Learning: The TFTP driver (packages/jumpstarter-driver-tftp/jumpstarter_driver_tftp/driver.py) handles all low-level concerns like path validation, error handling, and checksum computation. The client (packages/jumpstarter-driver-tftp/jumpstarter_driver_tftp/client.py) should remain simple as it delegates these responsibilities to the driver.
Learnt from: bennyz
PR: jumpstarter-dev/jumpstarter#267
File: packages/jumpstarter-driver-tftp/jumpstarter_driver_tftp/driver.py:32-40
Timestamp: 2025-02-08T16:08:34.616Z
Learning: In the TFTP driver (jumpstarter_driver_tftp), the TFTP server component is read-only, while file management operations (upload, delete) are handled through the driver's client interface, not through the TFTP protocol itself.
packages/jumpstarter-driver-flashers/jumpstarter_driver_flashers/driver_test.py (3)
Learnt from: bennyz
PR: jumpstarter-dev/jumpstarter#241
File: packages/jumpstarter-driver-tftp/jumpstarter_driver_tftp/client.py:52-60
Timestamp: 2025-01-29T11:52:43.554Z
Learning: The TFTP driver (packages/jumpstarter-driver-tftp/jumpstarter_driver_tftp/driver.py) handles all low-level concerns like path validation, error handling, and checksum computation. The client (packages/jumpstarter-driver-tftp/jumpstarter_driver_tftp/client.py) should remain simple as it delegates these responsibilities to the driver.
Learnt from: bennyz
PR: jumpstarter-dev/jumpstarter#267
File: packages/jumpstarter-driver-tftp/jumpstarter_driver_tftp/driver.py:32-40
Timestamp: 2025-02-08T16:08:34.616Z
Learning: In the TFTP driver (jumpstarter_driver_tftp), the TFTP server component is read-only, while file management operations (upload, delete) are handled through the driver's client interface, not through the TFTP protocol itself.
Learnt from: bennyz
PR: jumpstarter-dev/jumpstarter#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.
packages/jumpstarter-driver-flashers/jumpstarter_driver_flashers/driver.py (2)
Learnt from: bennyz
PR: jumpstarter-dev/jumpstarter#241
File: packages/jumpstarter-driver-tftp/jumpstarter_driver_tftp/client.py:52-60
Timestamp: 2025-01-29T11:52:43.554Z
Learning: The TFTP driver (packages/jumpstarter-driver-tftp/jumpstarter_driver_tftp/driver.py) handles all low-level concerns like path validation, error handling, and checksum computation. The client (packages/jumpstarter-driver-tftp/jumpstarter_driver_tftp/client.py) should remain simple as it delegates these responsibilities to the driver.
Learnt from: bennyz
PR: jumpstarter-dev/jumpstarter#267
File: packages/jumpstarter-driver-tftp/jumpstarter_driver_tftp/driver.py:32-40
Timestamp: 2025-02-08T16:08:34.616Z
Learning: In the TFTP driver (jumpstarter_driver_tftp), the TFTP server component is read-only, while file management operations (upload, delete) are handled through the driver's client interface, not through the TFTP protocol itself.
🧬 Code Graph Analysis (3)
packages/jumpstarter-driver-flashers/jumpstarter_driver_flashers/client.py (2)
packages/jumpstarter/jumpstarter/client/base.py (1)
  • call (36-46)
examples/soc-pytest/jumpstarter_example_soc_pytest/test_on_rpi4.py (1)
  • console (20-24)
packages/jumpstarter-driver-flashers/jumpstarter_driver_flashers/test_bundle.py (1)
packages/jumpstarter-driver-flashers/jumpstarter_driver_flashers/bundle.py (3)
  • FlasherBundleManifestV1Alpha1 (46-114)
  • from_file (106-109)
  • get_boot_cmd (72-87)
packages/jumpstarter-driver-flashers/jumpstarter_driver_flashers/driver_test.py (3)
packages/jumpstarter-driver-flashers/jumpstarter_driver_flashers/driver.py (1)
  • client (63-64)
packages/jumpstarter/jumpstarter/client/core.py (1)
  • DriverInvalidArgument (44-47)
packages/jumpstarter/jumpstarter/client/base.py (1)
  • call (36-46)
🪛 Shellcheck (0.10.0)
packages/jumpstarter-driver-flashers/oci_bundles/aarch64-itb/replace_kernel.sh

[warning] 19-19: Use 'pushd ... || exit' or 'pushd ... || return' in case pushd fails.

(SC2164)


[warning] 24-24: Quote to prevent word splitting/globbing, or split robustly with mapfile or read -a.

(SC2206)


[warning] 25-25: Quote to prevent word splitting/globbing, or split robustly with mapfile or read -a.

(SC2206)


[warning] 26-26: Quote to prevent word splitting/globbing, or split robustly with mapfile or read -a.

(SC2206)


[error] 46-46: Double quote array expansions to avoid re-splitting elements.

(SC2068)


[warning] 50-50: Use 'popd ... || exit' or 'popd ... || return' in case popd fails.

(SC2164)

🪛 Pylint (3.3.7)
packages/jumpstarter-driver-flashers/jumpstarter_driver_flashers/bundle.py

[refactor] 16-16: Too few public methods (0/2)

(R0903)


[refactor] 67-70: Unnecessary "else" after "return", remove the "else" and de-indent the code inside it

(R1705)


[refactor] 82-85: Unnecessary "else" after "return", remove the "else" and de-indent the code inside it

(R1705)

packages/jumpstarter-driver-flashers/jumpstarter_driver_flashers/driver.py

[refactor] 186-189: Unnecessary "else" after "return", remove the "else" and de-indent the code inside it

(R1705)

🪛 Flake8 (7.2.0)
packages/jumpstarter-driver-flashers/jumpstarter_driver_flashers/bundle.py

[error] 16-16: expected 2 blank lines, found 1

(E302)

⏰ Context from checks skipped due to timeout of 90000ms (7)
  • GitHub Check: e2e
  • GitHub Check: pytest-matrix (ubuntu-24.04, 3.13)
  • GitHub Check: pytest-matrix (macos-15, 3.12)
  • GitHub Check: pytest-matrix (macos-15, 3.11)
  • GitHub Check: pytest-matrix (macos-15, 3.13)
  • GitHub Check: pytest-matrix (ubuntu-24.04, 3.11)
  • GitHub Check: pytest-matrix (ubuntu-24.04, 3.12)
🔇 Additional comments (8)
packages/jumpstarter-driver-flashers/oci_bundles/test/manifest.yaml (1)

34-39: LGTM! Enhanced DTB variant structure enables flexible boot command handling.

The restructuring from simple file mappings to structured objects with optional file and bootcmd fields provides better flexibility for variant-specific boot commands while maintaining clarity.

packages/jumpstarter-driver-flashers/jumpstarter_driver_flashers/client.py (1)

415-418: LGTM! Dynamic boot command retrieval enables variant-aware functionality.

The change from static manifest.spec.bootcmd to dynamic self.call("get_bootcmd") correctly implements the new variant-aware boot command logic, allowing different DTB variants to specify custom boot commands.

packages/jumpstarter-driver-flashers/oci_bundles/aarch64-itb/build_fits.sh (1)

1-21: LGTM! Script follows good practices with room for minor improvements.

The script correctly uses set -euo pipefail for error handling and follows a logical build process for creating both buildroot and automotive FIT images.

packages/jumpstarter-driver-flashers/oci_bundles/aarch64-itb/manifest-automotive.yaml (1)

1-29: LGTM! Manifest structure aligns with new DTB variant model.

The manifest correctly uses the new structured DTB variant format with variant-specific boot commands, enabling flexible configuration for different R-Car S4 board variants.

packages/jumpstarter-driver-flashers/jumpstarter_driver_flashers/test_bundle.py (2)

3-3: LGTM! Added pytest import for enhanced test functionality.

The pytest import is correctly added to support the new test functions that use pytest.raises for error handling tests.


20-54: LGTM! Comprehensive test coverage for new get_boot_cmd functionality.

The new test functions provide excellent coverage of the get_boot_cmd method:

  • Default behavior without variant specification
  • Variant-specific boot commands
  • Fallback to default when variant lacks custom bootcmd
  • Proper error handling for invalid variants

The tests are well-structured with descriptive names and clear assertions.

packages/jumpstarter-driver-flashers/jumpstarter_driver_flashers/driver_test.py (1)

9-143: Comprehensive test coverage for the new boot command functionality!

The tests effectively cover all scenarios including default, variant-specific, and error cases. The test suite properly validates the new DTB variant-aware boot command retrieval.

packages/jumpstarter-driver-flashers/oci_bundles/aarch64-itb/replace_kernel.sh (1)

50-50: Add error handling for popd.

-popd
+popd || exit 1
⛔ Skipped due to learnings
Learnt from: mangelajo
PR: jumpstarter-dev/jumpstarter#339
File: packages/jumpstarter-driver-flashers/oci_bundles/build_bundle.sh:12-12
Timestamp: 2025-03-12T16:55:13.031Z
Learning: For shell scripts in the Jumpstarter project, prefer using `set -e` at the beginning of scripts to handle errors consistently throughout, rather than adding explicit error checks like `|| exit 1` for individual commands.

[ $# -ne 1 ] && { echo "$0 [target_overlay_dir]"; exit 1; }
ODIR=$1
mkdir -p /kernel-automotive
pushd /kernel-automotive
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

Add error handling for directory navigation.

The pushd command can fail if the directory doesn't exist or permissions are insufficient.

-pushd /kernel-automotive
+pushd /kernel-automotive || exit 1
📝 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
pushd /kernel-automotive
pushd /kernel-automotive || exit 1
🧰 Tools
🪛 Shellcheck (0.10.0)

[warning] 19-19: Use 'pushd ... || exit' or 'pushd ... || return' in case pushd fails.

(SC2164)

🤖 Prompt for AI Agents
In
packages/jumpstarter-driver-flashers/oci_bundles/aarch64-itb/replace_kernel.sh
at line 19, the pushd command lacks error handling for directory navigation
failures. Modify the script to check if pushd succeeds by testing its exit
status immediately after the command. If pushd fails, output an error message
and exit the script to prevent further execution in an invalid directory
context.

@mangelajo mangelajo force-pushed the buildroot_flasher branch from 7ae7c05 to b71052e Compare June 26, 2025 15:45
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: 0

♻️ Duplicate comments (1)
packages/jumpstarter-driver-flashers/jumpstarter_driver_flashers/driver.py (1)

185-189: Fix redundant method call and unnecessary else clause.

This issue was identified in previous reviews but remains unfixed. The method calls get_dtb_file twice unnecessarily.

     async def get_dtb_filename(self) -> str:
         """Return the dtb filename"""
         manifest = await self.get_flasher_manifest()
         dtb_file = manifest.get_dtb_file(self.variant)
         if dtb_file:
-            return Path(manifest.get_dtb_file(self.variant)).name
-        else:
-            return ""
+            return Path(dtb_file).name
+        return ""
🧹 Nitpick comments (3)
packages/jumpstarter-driver-flashers/jumpstarter_driver_flashers/bundle.py (3)

16-19: Fix formatting and consider the static analysis warning.

The new Dtb model properly encapsulates DTB variant management. However, there are formatting issues to address.

+
 class Dtb(BaseModel):
     default: str
     address: str
     variants: dict[str, DtbVariant]

Note: The static analysis warning about "too few public methods" is a false positive for Pydantic models, which are primarily data containers.


57-70: Simplify control flow by removing unnecessary else clause.

The method logic is correct, but the else clause after return is redundant.

     def get_dtb_file(self, variant: str | None = None) -> str | None:
         if not self.spec.dtb:
             return None

         # if no variant is provided, use the default variant name from the manifest
         if not variant:
             variant = self.spec.dtb.default

         # look for the variant struct in this manifest
         variant_struct = self.spec.dtb.variants.get(variant)
         if variant_struct:
             return variant_struct.file
-        else:
-            raise ValueError(f"DTB variant {variant} not found in the manifest.")
+        raise ValueError(f"DTB variant {variant} not found in the manifest.")

72-87: Simplify control flow by removing unnecessary else clause.

The method implements proper fallback logic for boot commands. However, the else clause after return is redundant.

     def get_boot_cmd(self, variant: str | None = None) -> str:
         if not self.spec.dtb:
             return self.spec.bootcmd
         # if no variant is provided, use the default variant name from the manifest
         if not variant:
             variant = self.spec.dtb.default
         # look for the variant struct in this manifest
         variant_struct = self.spec.dtb.variants.get(variant)
         if variant_struct:
             # If variant has a custom bootcmd, use it; otherwise fall back to default
             if variant_struct.bootcmd:
                 return variant_struct.bootcmd
-            else:
-                return self.spec.bootcmd
-        else:
-            raise ValueError(f"DTB variant {variant} not found in the manifest.")
+            return self.spec.bootcmd
+        raise ValueError(f"DTB variant {variant} not found in the manifest.")
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 7ae7c05 and b71052e.

📒 Files selected for processing (8)
  • packages/jumpstarter-driver-flashers/README.md (1 hunks)
  • packages/jumpstarter-driver-flashers/jumpstarter_driver_flashers/bundle.py (4 hunks)
  • packages/jumpstarter-driver-flashers/jumpstarter_driver_flashers/client.py (1 hunks)
  • packages/jumpstarter-driver-flashers/jumpstarter_driver_flashers/driver.py (6 hunks)
  • packages/jumpstarter-driver-flashers/jumpstarter_driver_flashers/driver_test.py (3 hunks)
  • packages/jumpstarter-driver-flashers/jumpstarter_driver_flashers/test_bundle.py (2 hunks)
  • packages/jumpstarter-driver-flashers/oci_bundles/test/manifest.yaml (1 hunks)
  • packages/jumpstarter-driver-flashers/oci_bundles/ti_j784s4xevm/manifest.yaml (1 hunks)
✅ Files skipped from review due to trivial changes (1)
  • packages/jumpstarter-driver-flashers/README.md
🚧 Files skipped from review as they are similar to previous changes (5)
  • packages/jumpstarter-driver-flashers/jumpstarter_driver_flashers/client.py
  • packages/jumpstarter-driver-flashers/oci_bundles/ti_j784s4xevm/manifest.yaml
  • packages/jumpstarter-driver-flashers/oci_bundles/test/manifest.yaml
  • packages/jumpstarter-driver-flashers/jumpstarter_driver_flashers/test_bundle.py
  • packages/jumpstarter-driver-flashers/jumpstarter_driver_flashers/driver_test.py
🧰 Additional context used
🧠 Learnings (1)
packages/jumpstarter-driver-flashers/jumpstarter_driver_flashers/driver.py (2)
Learnt from: bennyz
PR: jumpstarter-dev/jumpstarter#241
File: packages/jumpstarter-driver-tftp/jumpstarter_driver_tftp/client.py:52-60
Timestamp: 2025-01-29T11:52:43.554Z
Learning: The TFTP driver (packages/jumpstarter-driver-tftp/jumpstarter_driver_tftp/driver.py) handles all low-level concerns like path validation, error handling, and checksum computation. The client (packages/jumpstarter-driver-tftp/jumpstarter_driver_tftp/client.py) should remain simple as it delegates these responsibilities to the driver.
Learnt from: bennyz
PR: jumpstarter-dev/jumpstarter#267
File: packages/jumpstarter-driver-tftp/jumpstarter_driver_tftp/driver.py:32-40
Timestamp: 2025-02-08T16:08:34.616Z
Learning: In the TFTP driver (jumpstarter_driver_tftp), the TFTP server component is read-only, while file management operations (upload, delete) are handled through the driver's client interface, not through the TFTP protocol itself.
🪛 Pylint (3.3.7)
packages/jumpstarter-driver-flashers/jumpstarter_driver_flashers/bundle.py

[refactor] 16-16: Too few public methods (0/2)

(R0903)


[refactor] 67-70: Unnecessary "else" after "return", remove the "else" and de-indent the code inside it

(R1705)


[refactor] 82-85: Unnecessary "else" after "return", remove the "else" and de-indent the code inside it

(R1705)

packages/jumpstarter-driver-flashers/jumpstarter_driver_flashers/driver.py

[refactor] 186-189: Unnecessary "else" after "return", remove the "else" and de-indent the code inside it

(R1705)

🪛 Flake8 (7.2.0)
packages/jumpstarter-driver-flashers/jumpstarter_driver_flashers/bundle.py

[error] 16-16: expected 2 blank lines, found 1

(E302)

⏰ Context from checks skipped due to timeout of 90000ms (7)
  • 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.11)
  • GitHub Check: pytest-matrix (macos-15, 3.13)
  • GitHub Check: pytest-matrix (macos-15, 3.12)
  • GitHub Check: pytest-matrix (ubuntu-24.04, 3.11)
  • GitHub Check: e2e
🔇 Additional comments (7)
packages/jumpstarter-driver-flashers/jumpstarter_driver_flashers/bundle.py (2)

2-2: Good modernization of imports.

The addition of Literal import supports the new type annotations used throughout the file.


13-15: Type annotations modernized correctly.

The explicit union types (None | str) are clearer than optional type hints and align with modern Python typing practices.

packages/jumpstarter-driver-flashers/jumpstarter_driver_flashers/driver.py (5)

20-21: Good refactoring to public attributes.

The transition from private _use_dtb to public variant attribute improves the API design and the new manifest attribute provides flexibility for different manifest files.


88-88: Correct integration with variant-aware DTB handling.

The method properly uses the new variant system to get the appropriate DTB file.


102-111: Enhanced validation with clear error messages.

The improved variant validation provides better error handling with specific details about available variants.


160-160: Consistent use of configurable manifest attribute.

The methods correctly use the manifest attribute instead of hardcoded filenames, improving flexibility.

Also applies to: 164-164


209-213: Well-implemented boot command retrieval.

The new method properly delegates to the manifest's variant-aware boot command logic.

michalskrivanek and others added 3 commits June 27, 2025 09:48
A single config building two FIT images supporting similar-enough boards using either upstream or kernel-automotive kernel.
Includes TI J784S4EVM, SK-AM69 and Renesas R-Car S4 Spider and SK.
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 (5)
packages/jumpstarter-driver-flashers/oci_bundles/aarch64-itb/replace_kernel.sh (3)

19-19: Wrap pushd with an exit fallback.
Same issue was flagged previously; the fix is still missing.

-pushd /kernel-automotive
+pushd /kernel-automotive || exit 1

24-27: Quote each element in the pkgs array.
Prevents glob expansion or word-splitting when $KVER changes.

-pkgs=(
-	kernel-automotive-core-$KVER.rpm
-	kernel-automotive-modules-$KVER.rpm
-	kernel-automotive-modules-core-$KVER.rpm
-)
+pkgs=(
+	"kernel-automotive-core-$KVER.rpm"
+	"kernel-automotive-modules-$KVER.rpm"
+	"kernel-automotive-modules-core-$KVER.rpm"
+)

46-48: Quote the KMOD array expansion in the loop.

Unquoted ${KMOD[@]} triggers re-splitting; Shellcheck SC2068 already points this out.

-for mod in ${KMOD[@]}; do
+for mod in "${KMOD[@]}"; do
packages/jumpstarter-driver-flashers/oci_bundles/aarch64-itb/manifest-buildroot.yaml (1)

48-48: Fix YAML syntax error - missing colon.

The line is missing a colon after bootcmd, which will cause YAML parsing to fail.

       custom:
-        bootcmd "bootm 0x90000000:kernel 0x90000000:initrd 0x88000000"
+        bootcmd: "bootm 0x90000000:kernel 0x90000000:initrd 0x88000000"
packages/jumpstarter-driver-flashers/jumpstarter_driver_flashers/driver.py (1)

185-189: Optimize method calls and simplify control flow.

The code calls get_dtb_file twice unnecessarily and has redundant else block.

         dtb_file = manifest.get_dtb_file(self.variant)
         if dtb_file:
-            return Path(manifest.get_dtb_file(self.variant)).name
-        else:
-            return ""
+            return Path(dtb_file).name
+        return ""
🧹 Nitpick comments (5)
packages/jumpstarter-driver-flashers/oci_bundles/aarch64-itb/replace_kernel.sh (2)

50-50: Handle popd failure symmetrically.

-popd
+popd || exit 1

52-57: Quote $ODIR to survive spaces and weird paths.

-mkdir -p $ODIR/lib/modules $ODIR/etc/init.d || exit 1
+mkdir -p "$ODIR/lib/modules" "$ODIR/etc/init.d" || exit 1
 ...
-	mkdir -p "$ODIR$(dirname $mod)"
-	zstd -d "/kernel-automotive$mod.zst" -o "$ODIR$mod"
+	mkdir -p "$ODIR$(dirname "$mod")"
+	zstd -d "/kernel-automotive$mod.zst" -o "$ODIR$mod"
packages/jumpstarter-driver-flashers/jumpstarter_driver_flashers/bundle.py (3)

16-19: Fix formatting and consider adding methods to the Dtb class.

The class needs proper spacing and could benefit from utility methods.

+
 class Dtb(BaseModel):
     default: str
     address: str
     variants: dict[str, DtbVariant]

Consider adding utility methods like get_variant_names() or has_variant(name: str) to improve usability.


67-70: Remove unnecessary else block after return.

The else block is redundant since the if block returns.

         variant_struct = self.spec.dtb.variants.get(variant)
         if variant_struct:
             return variant_struct.file
-        else:
-            raise ValueError(f"DTB variant {variant} not found in the manifest.")
+        raise ValueError(f"DTB variant {variant} not found in the manifest.")

72-87: Simplify control flow by removing unnecessary else block.

Similar to the previous method, the else block is redundant.

         variant_struct = self.spec.dtb.variants.get(variant)
         if variant_struct:
             # If variant has a custom bootcmd, use it; otherwise fall back to default
             if variant_struct.bootcmd:
                 return variant_struct.bootcmd
-            else:
-                return self.spec.bootcmd
-        else:
-            raise ValueError(f"DTB variant {variant} not found in the manifest.")
+            return self.spec.bootcmd
+        raise ValueError(f"DTB variant {variant} not found in the manifest.")
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between b71052e and 95a7f1f.

📒 Files selected for processing (16)
  • packages/jumpstarter-driver-flashers/README.md (1 hunks)
  • packages/jumpstarter-driver-flashers/jumpstarter_driver_flashers/bundle.py (4 hunks)
  • packages/jumpstarter-driver-flashers/jumpstarter_driver_flashers/client.py (1 hunks)
  • packages/jumpstarter-driver-flashers/jumpstarter_driver_flashers/driver.py (6 hunks)
  • packages/jumpstarter-driver-flashers/jumpstarter_driver_flashers/driver_test.py (3 hunks)
  • packages/jumpstarter-driver-flashers/jumpstarter_driver_flashers/test_bundle.py (2 hunks)
  • packages/jumpstarter-driver-flashers/oci_bundles/aarch64-itb/automotive.its (1 hunks)
  • packages/jumpstarter-driver-flashers/oci_bundles/aarch64-itb/build_fits.sh (1 hunks)
  • packages/jumpstarter-driver-flashers/oci_bundles/aarch64-itb/buildroot.its (1 hunks)
  • packages/jumpstarter-driver-flashers/oci_bundles/aarch64-itb/buildroot_defconfig (1 hunks)
  • packages/jumpstarter-driver-flashers/oci_bundles/aarch64-itb/manifest-automotive.yaml (1 hunks)
  • packages/jumpstarter-driver-flashers/oci_bundles/aarch64-itb/manifest-buildroot.yaml (1 hunks)
  • packages/jumpstarter-driver-flashers/oci_bundles/aarch64-itb/overlay/etc/network/if-pre-up.d/wait-carrier.sh (1 hunks)
  • packages/jumpstarter-driver-flashers/oci_bundles/aarch64-itb/replace_kernel.sh (1 hunks)
  • packages/jumpstarter-driver-flashers/oci_bundles/test/manifest.yaml (1 hunks)
  • packages/jumpstarter-driver-flashers/oci_bundles/ti_j784s4xevm/manifest.yaml (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (12)
  • packages/jumpstarter-driver-flashers/jumpstarter_driver_flashers/client.py
  • packages/jumpstarter-driver-flashers/oci_bundles/ti_j784s4xevm/manifest.yaml
  • packages/jumpstarter-driver-flashers/oci_bundles/test/manifest.yaml
  • packages/jumpstarter-driver-flashers/oci_bundles/aarch64-itb/buildroot.its
  • packages/jumpstarter-driver-flashers/oci_bundles/aarch64-itb/automotive.its
  • packages/jumpstarter-driver-flashers/README.md
  • packages/jumpstarter-driver-flashers/oci_bundles/aarch64-itb/overlay/etc/network/if-pre-up.d/wait-carrier.sh
  • packages/jumpstarter-driver-flashers/oci_bundles/aarch64-itb/build_fits.sh
  • packages/jumpstarter-driver-flashers/oci_bundles/aarch64-itb/manifest-automotive.yaml
  • packages/jumpstarter-driver-flashers/oci_bundles/aarch64-itb/buildroot_defconfig
  • packages/jumpstarter-driver-flashers/jumpstarter_driver_flashers/test_bundle.py
  • packages/jumpstarter-driver-flashers/jumpstarter_driver_flashers/driver_test.py
🧰 Additional context used
🧠 Learnings (2)
packages/jumpstarter-driver-flashers/jumpstarter_driver_flashers/driver.py (2)
Learnt from: bennyz
PR: jumpstarter-dev/jumpstarter#241
File: packages/jumpstarter-driver-tftp/jumpstarter_driver_tftp/client.py:52-60
Timestamp: 2025-01-29T11:52:43.554Z
Learning: The TFTP driver (packages/jumpstarter-driver-tftp/jumpstarter_driver_tftp/driver.py) handles all low-level concerns like path validation, error handling, and checksum computation. The client (packages/jumpstarter-driver-tftp/jumpstarter_driver_tftp/client.py) should remain simple as it delegates these responsibilities to the driver.
Learnt from: bennyz
PR: jumpstarter-dev/jumpstarter#267
File: packages/jumpstarter-driver-tftp/jumpstarter_driver_tftp/driver.py:32-40
Timestamp: 2025-02-08T16:08:34.616Z
Learning: In the TFTP driver (jumpstarter_driver_tftp), the TFTP server component is read-only, while file management operations (upload, delete) are handled through the driver's client interface, not through the TFTP protocol itself.
packages/jumpstarter-driver-flashers/oci_bundles/aarch64-itb/replace_kernel.sh (2)
Learnt from: mangelajo
PR: jumpstarter-dev/jumpstarter#339
File: packages/jumpstarter-driver-flashers/oci_bundles/build_bundle.sh:12-12
Timestamp: 2025-03-12T16:55:13.031Z
Learning: For shell scripts in the Jumpstarter project, prefer using `set -e` at the beginning of scripts to handle errors consistently throughout, rather than adding explicit error checks like `|| exit 1` for individual commands.
Learnt from: mangelajo
PR: jumpstarter-dev/jumpstarter#339
File: packages/jumpstarter-driver-flashers/jumpstarter_driver_flashers/client.py:172-172
Timestamp: 2025-03-14T15:52:49.790Z
Learning: Shell command sanitization (using shlex.quote or similar) is not required in the flasher driver context because it operates on devices where full control is already assumed, as the code is flashing the entire disk.
🧬 Code Graph Analysis (1)
packages/jumpstarter-driver-flashers/jumpstarter_driver_flashers/driver.py (2)
packages/jumpstarter-driver-flashers/jumpstarter_driver_flashers/client.py (1)
  • manifest (455-462)
packages/jumpstarter-driver-flashers/jumpstarter_driver_flashers/bundle.py (3)
  • get_dtb_file (57-70)
  • FlasherBundleManifestV1Alpha1 (46-114)
  • get_boot_cmd (72-87)
🪛 Pylint (3.3.7)
packages/jumpstarter-driver-flashers/jumpstarter_driver_flashers/bundle.py

[refactor] 16-16: Too few public methods (0/2)

(R0903)


[refactor] 67-70: Unnecessary "else" after "return", remove the "else" and de-indent the code inside it

(R1705)


[refactor] 82-85: Unnecessary "else" after "return", remove the "else" and de-indent the code inside it

(R1705)

packages/jumpstarter-driver-flashers/jumpstarter_driver_flashers/driver.py

[refactor] 186-189: Unnecessary "else" after "return", remove the "else" and de-indent the code inside it

(R1705)

🪛 Flake8 (7.2.0)
packages/jumpstarter-driver-flashers/jumpstarter_driver_flashers/bundle.py

[error] 16-16: expected 2 blank lines, found 1

(E302)

🪛 Shellcheck (0.10.0)
packages/jumpstarter-driver-flashers/oci_bundles/aarch64-itb/replace_kernel.sh

[warning] 19-19: Use 'pushd ... || exit' or 'pushd ... || return' in case pushd fails.

(SC2164)


[warning] 24-24: Quote to prevent word splitting/globbing, or split robustly with mapfile or read -a.

(SC2206)


[warning] 25-25: Quote to prevent word splitting/globbing, or split robustly with mapfile or read -a.

(SC2206)


[warning] 26-26: Quote to prevent word splitting/globbing, or split robustly with mapfile or read -a.

(SC2206)


[error] 46-46: Double quote array expansions to avoid re-splitting elements.

(SC2068)


[warning] 50-50: Use 'popd ... || exit' or 'popd ... || return' in case popd fails.

(SC2164)

⏰ Context from checks skipped due to timeout of 90000ms (10)
  • GitHub Check: Redirect rules - jumpstarter-docs
  • GitHub Check: Header rules - jumpstarter-docs
  • GitHub Check: Pages changed - jumpstarter-docs
  • GitHub Check: pytest-matrix (macos-15, 3.11)
  • GitHub Check: pytest-matrix (macos-15, 3.12)
  • GitHub Check: pytest-matrix (macos-15, 3.13)
  • GitHub Check: pytest-matrix (ubuntu-24.04, 3.12)
  • GitHub Check: pytest-matrix (ubuntu-24.04, 3.13)
  • GitHub Check: pytest-matrix (ubuntu-24.04, 3.11)
  • GitHub Check: e2e
🔇 Additional comments (6)
packages/jumpstarter-driver-flashers/oci_bundles/aarch64-itb/replace_kernel.sh (1)

41-42: Confirm unzboot is available in the build environment.

unzboot isn’t a standard util; if it’s a local helper ensure it’s on $PATH or add an explicit check.

packages/jumpstarter-driver-flashers/jumpstarter_driver_flashers/bundle.py (1)

13-14: LGTM - Modern type hint syntax.

The migration from Optional[str] to None | str follows modern Python type annotation practices.

packages/jumpstarter-driver-flashers/jumpstarter_driver_flashers/driver.py (4)

20-21: LGTM - Well-designed variant support.

The addition of variant and manifest fields provides flexibility for DTB variant selection and custom manifest files.


88-88: Good integration of variant support in DTB file retrieval.

The method correctly passes the variant to get_dtb_file for variant-aware DTB selection.


102-111: Excellent validation logic for DTB variants.

The method properly validates that the requested variant exists in the manifest and provides helpful error messages with available variants.


209-213: LGTM - Clean implementation of boot command retrieval.

The new method provides a clean interface for retrieving variant-aware boot commands from the manifest.

Comment on lines +1 to +2
#!/bin/bash

Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Add set -euo pipefail right after the shebang.

Fail-fast behaviour is expected for our flasher scripts (see project learning).
This single line removes the need for scattered || exit 1 and gives us safer default handling of unset vars and pipe errors.

 #!/bin/bash
+set -euo pipefail
🤖 Prompt for AI Agents
In
packages/jumpstarter-driver-flashers/oci_bundles/aarch64-itb/replace_kernel.sh
at the very beginning (lines 1-2), add the line `set -euo pipefail` immediately
after the shebang `#!/bin/bash`. This will enable fail-fast behavior by causing
the script to exit on any error, unset variable usage, or pipe failure,
improving script safety and removing the need for multiple explicit exit checks.

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: 2

🧹 Nitpick comments (1)
packages/jumpstarter-driver-flashers/oci_bundles/build_bundle.sh (1)

24-27: Quote variable expansions or switch to arrays to preserve filenames with spaces

$MANIFESTS and $DATA_FILES are expanded unquoted, so any embedded whitespace will be treated as argument separators by the shell before reaching oras push. After the refactors above, consider building an array and using oras push "${params[@]}" or, at minimum, wrapping each file entry in double quotes when constructing the strings.

This protects against subtle bugs if future artifacts or manifests use filenames containing spaces.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 95a7f1f and 41cb2e2.

📒 Files selected for processing (4)
  • packages/jumpstarter-driver-flashers/oci_bundles/aarch64-itb/manifest-renesas.yaml (1 hunks)
  • packages/jumpstarter-driver-flashers/oci_bundles/aarch64-itb/manifest-ti.yaml (1 hunks)
  • packages/jumpstarter-driver-flashers/oci_bundles/aarch64-itb/manifest.yaml (1 hunks)
  • packages/jumpstarter-driver-flashers/oci_bundles/build_bundle.sh (1 hunks)
✅ Files skipped from review due to trivial changes (3)
  • packages/jumpstarter-driver-flashers/oci_bundles/aarch64-itb/manifest.yaml
  • packages/jumpstarter-driver-flashers/oci_bundles/aarch64-itb/manifest-renesas.yaml
  • packages/jumpstarter-driver-flashers/oci_bundles/aarch64-itb/manifest-ti.yaml
🧰 Additional context used
🪛 Shellcheck (0.10.0)
packages/jumpstarter-driver-flashers/oci_bundles/build_bundle.sh

[warning] 16-16: Iterating over ls output is fragile. Use globs.

(SC2045)


[warning] 20-20: For loops over find output are fragile. Use find -exec or a while read loop.

(SC2044)

⏰ Context from checks skipped due to timeout of 90000ms (7)
  • GitHub Check: pytest-matrix (macos-15, 3.11)
  • GitHub Check: pytest-matrix (macos-15, 3.13)
  • GitHub Check: pytest-matrix (macos-15, 3.12)
  • GitHub Check: pytest-matrix (ubuntu-24.04, 3.13)
  • GitHub Check: pytest-matrix (ubuntu-24.04, 3.12)
  • GitHub Check: pytest-matrix (ubuntu-24.04, 3.11)
  • GitHub Check: e2e

@michalskrivanek michalskrivanek force-pushed the buildroot_flasher branch 2 times, most recently from abb6b86 to 4995806 Compare June 27, 2025 14:28
all *.yaml files are treated as manifests. A default manifest manifest.yaml should still exist
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 (2)
packages/jumpstarter-driver-flashers/oci_bundles/build_bundle.sh (2)

15-18: for file in $(ls …) is still unsafe & was already flagged

The loop continues to rely on command-substituted ls, which breaks on filenames containing spaces/newlines and trips Shellcheck SC2045. We recommended switching to direct globbing with an existence guard in a previous review but the change hasn’t been applied. Re-using the earlier diff:

-MANIFESTS=
-for file in $(ls -1 *.yaml); do
-	MANIFESTS="${MANIFESTS} ${file}:application/yaml "
-done
+MANIFESTS=
+for file in *.yaml; do
+    [ -e "$file" ] || continue   # skip when the glob expands to literal '*.yaml'
+    MANIFESTS="${MANIFESTS}${file}:application/yaml "
+done

20-22: Whitespace-fragile find … | for loop persists

The find iteration still uses plain word-splitting, reproducing SC2044 issues previously reported. Please adopt a null-delimited approach:

-DATA_FILES=
-for file in $(find ./data -type f -prune -a -not -name .gitkeep); do
-	DATA_FILES="${DATA_FILES} ${file}:application/octet-stream "
-done
+DATA_FILES=
+while IFS= read -r -d '' file; do
+    DATA_FILES="${DATA_FILES}${file}:application/octet-stream "
+done < <(find ./data -type f ! -name '.gitkeep' -print0)
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 4995806 and ea20e29.

📒 Files selected for processing (5)
  • packages/jumpstarter-driver-flashers/oci_bundles/aarch64-itb/manifest-renesas.yaml (1 hunks)
  • packages/jumpstarter-driver-flashers/oci_bundles/aarch64-itb/manifest-ti.yaml (1 hunks)
  • packages/jumpstarter-driver-flashers/oci_bundles/aarch64-itb/manifest.yaml (1 hunks)
  • packages/jumpstarter-driver-flashers/oci_bundles/aarch64-itb/overlay/etc/udev/rules.d/10-rename-tsn0.rules (1 hunks)
  • packages/jumpstarter-driver-flashers/oci_bundles/build_bundle.sh (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (4)
  • packages/jumpstarter-driver-flashers/oci_bundles/aarch64-itb/overlay/etc/udev/rules.d/10-rename-tsn0.rules
  • packages/jumpstarter-driver-flashers/oci_bundles/aarch64-itb/manifest.yaml
  • packages/jumpstarter-driver-flashers/oci_bundles/aarch64-itb/manifest-renesas.yaml
  • packages/jumpstarter-driver-flashers/oci_bundles/aarch64-itb/manifest-ti.yaml
🧰 Additional context used
🧠 Learnings (1)
packages/jumpstarter-driver-flashers/oci_bundles/build_bundle.sh (1)
Learnt from: mangelajo
PR: jumpstarter-dev/jumpstarter#339
File: packages/jumpstarter-driver-flashers/oci_bundles/build_bundle.sh:12-12
Timestamp: 2025-03-12T16:55:13.031Z
Learning: For shell scripts in the Jumpstarter project, prefer using `set -e` at the beginning of scripts to handle errors consistently throughout, rather than adding explicit error checks like `|| exit 1` for individual commands.
🪛 Shellcheck (0.10.0)
packages/jumpstarter-driver-flashers/oci_bundles/build_bundle.sh

[warning] 16-16: Iterating over ls output is fragile. Use globs.

(SC2045)


[warning] 20-20: For loops over find output are fragile. Use find -exec or a while read loop.

(SC2044)

⏰ Context from checks skipped due to timeout of 90000ms (7)
  • GitHub Check: pytest-matrix (ubuntu-24.04, 3.12)
  • GitHub Check: pytest-matrix (macos-15, 3.12)
  • GitHub Check: pytest-matrix (ubuntu-24.04, 3.11)
  • GitHub Check: pytest-matrix (macos-15, 3.11)
  • GitHub Check: pytest-matrix (macos-15, 3.13)
  • GitHub Check: pytest-matrix (ubuntu-24.04, 3.13)
  • GitHub Check: e2e

@mangelajo mangelajo changed the title [WIP] builroot-based flasher images builroot-based flasher images Jun 30, 2025
@mangelajo mangelajo requested a review from bennyz June 30, 2025 11:08
@mangelajo mangelajo force-pushed the buildroot_flasher branch from ec96675 to 3d1f825 Compare June 30, 2025 16:44
@mangelajo mangelajo enabled auto-merge June 30, 2025 16:45
@mangelajo mangelajo merged commit b38d41e into jumpstarter-dev:main Jun 30, 2025
18 checks passed
@coderabbitai coderabbitai bot mentioned this pull request Sep 23, 2025
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants