Skip to content

Use Docker BuildKit to build addons #5974

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 13 commits into
base: main
Choose a base branch
from

Conversation

felipecrs
Copy link
Contributor

@felipecrs felipecrs commented Jun 25, 2025

Proposed change

Use Docker BuildKit to build addons by delegating the build to a temporary container.

Type of change

  • Dependency upgrade
  • Bugfix (non-breaking change which fixes an issue)
  • New feature (which adds functionality to the supervisor)
  • Breaking change (fix/feature causing existing functionality to break)
  • Code quality improvements to existing code or addition of tests

Additional information

Tests made manually:

  • Build add-ons normally
  • When squash is set, ignore it and log a warning
  • Failed build should display logs in UI
chrome_R7mgN0sYbp.mp4

Checklist

  • The code change is tested and works locally.
  • Local tests pass. Your PR cannot be merged unless tests pass
  • There is no commented out code in this PR.
  • I have followed the development checklist
  • The code has been formatted using Ruff (ruff format supervisor tests)
  • Tests have been added to verify that the new code works.

If API endpoints or add-on configuration are added/changed:

Summary by CodeRabbit

  • Bug Fixes

    • Improved error reporting and handling during add-on image builds, especially when using the squash option.
    • Resolved issues with build argument construction and environment configuration for Docker builds.
  • Refactor

    • Switched add-on build process to use the Docker CLI instead of the Python SDK for greater compatibility and control.
    • Updated internal command handling to better support platform, tag, and environment variable options.
    • Enhanced container lifecycle management with improved command input flexibility and volume cleanup, including volume removal on container deletion.
  • Tests

    • Enhanced and expanded test coverage for Docker build commands, squash option behavior, and healthcheck scenarios.
    • Improved test mocks for Docker command execution and version handling.
    • Updated tests to verify volume removal during container cleanup.

@felipecrs felipecrs force-pushed the use-buildkit branch 2 times, most recently from a34507e to f380e1c Compare June 25, 2025 04:54
@felipecrs felipecrs marked this pull request as ready for review June 25, 2025 04:55
Copy link
Contributor

coderabbitai bot commented Jun 25, 2025

Warning

Rate limit exceeded

@felipecrs has exceeded the limit for the number of commits or files that can be reviewed per hour. Please wait 0 minutes and 34 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

📥 Commits

Reviewing files that changed from the base of the PR and between 6ad5846 and 6b22559.

📒 Files selected for processing (4)
  • supervisor/addons/build.py (1 hunks)
  • supervisor/docker/addon.py (3 hunks)
  • supervisor/docker/const.py (1 hunks)
  • supervisor/resolution/evaluations/container.py (2 hunks)
📝 Walkthrough

Walkthrough

The changes refactor the add-on build process to construct and execute Docker CLI commands directly, replacing the previous use of the Docker Python SDK for building images. The new approach assembles full Docker build commands with environment variables, volume bindings, and working directory. Related tests are updated to verify the new command-based build logic, including squash build options. Minor adjustments are made to Docker command execution and mocking in tests.

Changes

Files/Groups Change Summary
supervisor/addons/build.py Refactored get_docker_args to build and return a full Docker CLI build command with environment, volumes, and working directory; added helper method _fix_label; Dockerfile path computed relative to add-on path; labels and build args appended as CLI flags; build path transformed; volume bindings and working directory set.
supervisor/docker/addon.py Replaced Docker SDK image build with Docker CLI container run via run_command; legacy builder fallback and squash warning added; improved error handling and output decoding; removed old exception build log handling.
supervisor/docker/homeassistant.py Removed detach=True argument from run_command call in execute_command.
supervisor/docker/manager.py Updated run_command signature: renamed tag to version, accept command as string or list; combined image and version into image_tag; run container detached; container removal includes volume removal (v=True); default exit code to 1 if missing; volume removal added on container stop.
tests/addons/test_addon.py Modified tests to assert Docker CLI command execution via run_command instead of SDK build calls; added helper is_in_list to verify command argument order; updated container removal calls to include v=True.
tests/addons/test_build.py Updated tests to check Docker CLI command construction; refined assertions on platform and Dockerfile flags; added image tag argument to get_docker_args calls.
tests/api/test_addons.py Patched DockerAddon.healthcheck property and run_command method in rebuild healthcheck test to simulate successful build and healthcheck presence.
tests/conftest.py Enhanced DockerAPI mock: imported CommandReturn, set info.version as AwesomeVersion instance, and added mocked run_command returning successful build output.
tests/homeassistant/test_core.py Updated container removal assertions to include v=True volume removal flag.
tests/plugins/test_plugin_base.py Updated container removal assertion to include v=True alongside force=True.
tests/resolution/fixup/test_addon_execute_rebuild.py Updated container removal assertion to include v=True flag.
tests/resolution/fixup/test_core_execute_rebuild.py Updated container removal assertion to include v=True flag.

Sequence Diagram(s)

sequenceDiagram
    participant AddonBuild
    participant DockerAddon
    participant DockerAPI

    Note over AddonBuild: Build process starts
    AddonBuild->>AddonBuild: get_docker_args(version, image_tag)
    AddonBuild->>DockerAddon: Returns Docker CLI command, volumes, working_dir

    DockerAddon->>DockerAPI: run_command("docker", command, volumes, working_dir, env)
    DockerAPI->>Docker: Executes Docker CLI build command
    Docker->>DockerAPI: Returns build output and exit code

    alt Build successful
        DockerAPI->>DockerAddon: Return image and build log
    else Build failed
        DockerAPI->>DockerAddon: Raise DockerException with log
    end
Loading
sequenceDiagram
    participant Test
    participant AddonBuild

    Test->>AddonBuild: get_docker_args(version, image_tag)
    AddonBuild->>Test: Returns command list, volumes, working_dir

    Note over Test: Test asserts presence of flags (e.g., --platform, --file) and env (DOCKER_BUILDKIT)
Loading
✨ Finishing Touches
  • 📝 Generate Docstrings

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
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • 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 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 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 or @coderabbitai title 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 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 for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

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

🧹 Nitpick comments (2)
tests/addons/test_addon.py (1)

970-981: Useful helper function with minor formatting issue.

The is_in_list function is a good addition for verifying command argument order in lists. However, there's a formatting issue that should be addressed.

Apply this diff to fix the formatting issue flagged by static analysis:

-        if c in b:
-            b = b[b.index(c) :]
+        if c in b:
+            b = b[b.index(c):]
supervisor/docker/addon.py (1)

677-703: Consider enhancing error handling and logging.

The refactor to use Docker CLI is well-implemented. A few suggestions:

  1. The error message on line 697 could include more context about what might have gone wrong
  2. Consider adding progress logging for long builds since you have access to the build output

For better error diagnostics, consider parsing the build output for specific error patterns:

 if result.exit_code != 0:
-    error_message = f"The docker build command for {addon_image_tag} failed with exit code {result.exit_code}. Output:\n{log}"
+    error_message = f"Docker build failed for {addon_image_tag} (exit code: {result.exit_code})"
+    # Extract the last few meaningful lines for the error message
+    log_lines = log.strip().split('\n')
+    if log_lines:
+        error_details = '\n'.join(log_lines[-10:])  # Last 10 lines
+        error_message += f"\nBuild output (last 10 lines):\n{error_details}"
     raise docker.errors.DockerException(error_message)
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
Cache: Disabled due to data retention organization setting
Knowledge Base: Disabled due to data retention organization setting

📥 Commits

Reviewing files that changed from the base of the PR and between 0b79e09 and f380e1c.

📒 Files selected for processing (8)
  • supervisor/addons/build.py (1 hunks)
  • supervisor/docker/addon.py (2 hunks)
  • supervisor/docker/homeassistant.py (1 hunks)
  • supervisor/docker/manager.py (3 hunks)
  • tests/addons/test_addon.py (3 hunks)
  • tests/addons/test_build.py (5 hunks)
  • tests/api/test_addons.py (1 hunks)
  • tests/conftest.py (2 hunks)
🧰 Additional context used
📓 Path-based instructions (6)
`*/**(html|markdown|md)`: - For instructional content in documentation, use a direct and authoritative tone. Avoid expressions of politeness such as 'may' or 'please', and ensure t...

*/**(html|markdown|md): - For instructional content in documentation, use a direct and authoritative tone. Avoid expressions of politeness such as 'may' or 'please', and ensure the goal of the instruction is fronted.

  • Apply the Microsoft Style Guide to ensure documentation maintains clarity and conciseness.
  • In step-by-step instructions, front the location phrase in the instructional sentence.
  • In step-by-step instructions, front the 'goal' in the instructional sentence.
  • In step-by-step instructions, if in doubt what to front, front the 'goal' before the location phrase in the instructional sentence.
  • do not hyphenate terms like 'top-right' or 'bottom-left' with 'corner'
  • tests/conftest.py
`*/**(html|markdown|md)`: - Use bold to mark UI strings. - If "" are used to mark UI strings, replace them by bold.

*/**(html|markdown|md): - Use bold to mark UI strings.

  • If "" are used to mark UI strings, replace them by bold.
  • tests/conftest.py
`*/**(html|markdown|md)`: - Be brief in your replies and don't add fluff like "thank you for..." and "Please let me know if"

*/**(html|markdown|md): - Be brief in your replies and don't add fluff like "thank you for..." and "Please let me know if"

  • tests/conftest.py
`*/**(html|markdown|md)`: - Use sentence-style capitalization also in headings.

*/**(html|markdown|md): - Use sentence-style capitalization also in headings.

  • tests/conftest.py
`*/**(html|markdown|md)`: do not comment on HTML used for icons

*/**(html|markdown|md): do not comment on HTML used for icons

  • tests/conftest.py
`*/**(html|markdown|md)`: Avoid flagging inline HTML for embedding videos in future reviews for this repository.

*/**(html|markdown|md): Avoid flagging inline HTML for embedding videos in future reviews for this repository.

  • tests/conftest.py
🪛 Flake8 (7.2.0)
tests/addons/test_addon.py

[error] 978-978: whitespace before ':'

(E203)

⏰ Context from checks skipped due to timeout of 90000ms (4)
  • GitHub Check: Build aarch64 supervisor
  • GitHub Check: Build armv7 supervisor
  • GitHub Check: Build armhf supervisor
  • GitHub Check: Run tests Python 3.13.3
🔇 Additional comments (18)
supervisor/docker/homeassistant.py (1)

211-211: LGTM! Parameter rename aligns with updated method signature.

The change from version to tag is consistent with the updated run_command method signature in supervisor/docker/manager.py. This maintains consistency across the Docker command interface.

tests/api/test_addons.py (1)

242-244: Enhanced mocking supports the new Docker addon behavior.

The additional patch on DockerAddon.healthcheck properly mocks the healthcheck presence during addon rebuilds, supporting the updated Docker CLI command flow introduced in the broader refactor.

tests/conftest.py (2)

47-47: Enhanced imports support the new command execution interface.

Adding CommandReturn import enables proper mocking of the Docker CLI command execution flow.


134-138: Improved Docker fixture mocking aligns with refactored command execution.

The changes provide more accurate version representation using AwesomeVersion and mock the new run_command method with a successful CommandReturn object, supporting the transition from Docker SDK to CLI commands.

tests/addons/test_addon.py (2)

855-867: Test correctly updated to verify Docker CLI command execution.

The test properly checks run_command calls instead of Docker SDK build calls, verifying the correct Docker CLI command structure including platform and tag arguments. This aligns with the new build process using Docker CLI commands.


884-896: Consistent test update maintains coverage for the new build flow.

Similar to the previous test, this correctly verifies the Docker CLI command invocation with proper platform and tag arguments, ensuring test coverage for the refactored build process.

supervisor/docker/manager.py (5)

298-298: Enhanced parameter flexibility supports diverse command inputs.

Expanding the command parameter to accept strings, lists, or None provides better flexibility for different types of Docker CLI commands and aligns with Docker's command execution patterns.


308-310: Improved image handling and logging consistency.

Constructing the full image_tag upfront and using it consistently in logging and container execution provides better clarity and consistency throughout the method.


317-317: Detached mode default improves command execution reliability.

Setting detach=True by default ensures consistent container execution behavior and allows for proper wait/cleanup handling in the command execution flow.


333-333: Volume cleanup prevents resource leaks.

Adding v=True to container removal ensures associated volumes are cleaned up, preventing potential resource leaks during temporary container operations.


335-335: Robust error handling with sensible default.

Defaulting the exit code to 1 when StatusCode is missing provides a sensible fallback that indicates failure, improving the reliability of command execution result handling.

tests/addons/test_build.py (5)

12-31: LGTM! Test correctly adapted to new CLI interface.

The test properly verifies that the platform argument is included in the Docker build command with the correct value.


33-57: LGTM! Dockerfile path verification updated correctly.

The test properly checks that the --file argument is included in the command with the expected Dockerfile path.


59-83: LGTM! Architecture-specific Dockerfile test updated appropriately.

The test correctly verifies that the architecture-specific Dockerfile path is used when available.


113-140: Excellent test coverage for squash/BuildKit interaction!

This test thoroughly verifies the key behavior that squash option disables BuildKit and adds the necessary flags for legacy builder compatibility.


142-169: LGTM! Completes the test coverage for BuildKit behavior.

This test ensures that BuildKit remains enabled by default when squash is not used, which is the expected behavior for the new feature.

supervisor/addons/build.py (2)

129-200: Well-structured refactor to CLI-based build approach!

The conversion from Docker SDK parameters to CLI command construction is comprehensive and handles all the necessary build arguments, labels, and environment variables correctly. The BuildKit/squash handling aligns perfectly with the PR objectives.


186-189: ```shell
#!/bin/bash

Display lines 160-200 around the build_path manipulation in build.py

sed -n '160,200p' supervisor/addons/build.py


</details>

</blockquote></details>

</details>

<!-- This is an auto-generated comment by CodeRabbit for review status -->

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

🧹 Nitpick comments (1)
tests/addons/test_addon.py (1)

970-981: Fix formatting issue in the helper function.

The helper function logic is correct and useful for verifying command argument order. However, there's a whitespace formatting issue that should be addressed.

Apply this diff to fix the formatting:

-        if c in b:
-            b = b[b.index(c) :]
+        if c in b:
+            b = b[b.index(c):]
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
Cache: Disabled due to data retention organization setting
Knowledge Base: Disabled due to data retention organization setting

📥 Commits

Reviewing files that changed from the base of the PR and between f380e1c and 5b00846.

📒 Files selected for processing (8)
  • supervisor/addons/build.py (1 hunks)
  • supervisor/docker/addon.py (2 hunks)
  • supervisor/docker/homeassistant.py (1 hunks)
  • supervisor/docker/manager.py (4 hunks)
  • tests/addons/test_addon.py (3 hunks)
  • tests/addons/test_build.py (5 hunks)
  • tests/api/test_addons.py (1 hunks)
  • tests/conftest.py (2 hunks)
🚧 Files skipped from review as they are similar to previous changes (6)
  • supervisor/docker/homeassistant.py
  • tests/api/test_addons.py
  • tests/addons/test_build.py
  • tests/conftest.py
  • supervisor/docker/addon.py
  • supervisor/docker/manager.py
🧰 Additional context used
🪛 Flake8 (7.2.0)
tests/addons/test_addon.py

[error] 978-978: whitespace before ':'

(E203)

⏰ Context from checks skipped due to timeout of 90000ms (4)
  • GitHub Check: Build armhf supervisor
  • GitHub Check: Build armv7 supervisor
  • GitHub Check: Build aarch64 supervisor
  • GitHub Check: Run tests Python 3.13.3
🔇 Additional comments (4)
tests/addons/test_addon.py (2)

855-867: LGTM! Test correctly updated for CLI-based builds.

The test changes properly reflect the transition from Docker SDK images.build() calls to run_command() calls for the new CLI-based build process. The assertions correctly verify that the Docker CLI command includes the required platform specification and image tag.


884-896: LGTM! Consistent test update for missing image scenario.

The test correctly mirrors the changes in the previous test, properly verifying the CLI-based build approach for the missing image case.

supervisor/addons/build.py (2)

124-128: LGTM! Good code organization.

Moving the _fix_label method above get_docker_args improves readability since it's used within that method.


129-198: Excellent refactoring to support CLI-based builds!

This is a well-implemented transformation from Docker SDK parameters to a complete Docker CLI command structure. The implementation correctly:

  • Constructs the full docker build command with all necessary flags
  • Handles the squash option by disabling BuildKit and adding legacy builder flags
  • Sets up proper volume bindings for Docker socket access and addon files
  • Converts labels and build arguments to CLI format

The path mapping logic (removing /data/ prefix and prepending /mnt/supervisor/) aligns with the container-based build approach.

Please verify that the path mapping transformation is correct for all deployment scenarios:

#!/bin/bash
# Description: Verify addon path locations and the /data/ to /mnt/supervisor/ mapping

# Find addon path usage patterns
echo "=== Searching for addon path usage patterns ==="
rg -A 3 "path_location" --type py

echo -e "\n=== Searching for /data/ path references ==="
rg "/data/" --type py

echo -e "\n=== Searching for /mnt/supervisor/ references ==="
rg "/mnt/supervisor" --type py

@agners agners added the new-feature A new feature label Jun 25, 2025
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

🧹 Nitpick comments (1)
tests/addons/test_addon.py (1)

970-981: Fix whitespace formatting issue

The helper function logic is correct for checking ordered list elements, but there's a formatting issue flagged by static analysis.

Apply this diff to fix the whitespace issue:

-        if c in b:
-            b = b[b.index(c) :]
+        if c in b:
+            b = b[b.index(c):]
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
Cache: Disabled due to data retention organization setting
Knowledge Base: Disabled due to data retention organization setting

📥 Commits

Reviewing files that changed from the base of the PR and between 28ac828 and 648f37e.

📒 Files selected for processing (5)
  • tests/addons/test_addon.py (4 hunks)
  • tests/homeassistant/test_core.py (3 hunks)
  • tests/plugins/test_plugin_base.py (1 hunks)
  • tests/resolution/fixup/test_addon_execute_rebuild.py (1 hunks)
  • tests/resolution/fixup/test_core_execute_rebuild.py (1 hunks)
✅ Files skipped from review due to trivial changes (1)
  • tests/homeassistant/test_core.py
🧰 Additional context used
🪛 Flake8 (7.2.0)
tests/addons/test_addon.py

[error] 978-978: whitespace before ':'

(E203)

⏰ Context from checks skipped due to timeout of 90000ms (4)
  • GitHub Check: Build aarch64 supervisor
  • GitHub Check: Build armhf supervisor
  • GitHub Check: Build armv7 supervisor
  • GitHub Check: Run tests Python 3.13.3
🔇 Additional comments (6)
tests/plugins/test_plugin_base.py (1)

366-366: LGTM: Enhanced container cleanup with volume removal

The test correctly verifies that container removal now includes volume cleanup (v=True), which prevents volume accumulation and follows Docker best practices.

tests/resolution/fixup/test_addon_execute_rebuild.py (1)

79-81: LGTM: Consistent volume cleanup in addon rebuild

The assertion correctly verifies that addon container removal during rebuild includes volume cleanup (v=True), maintaining consistency with the enhanced cleanup behavior.

tests/resolution/fixup/test_core_execute_rebuild.py (1)

68-70: LGTM: Volume cleanup for core container removal

The test properly verifies that Home Assistant container removal includes volume cleanup (v=True), ensuring consistent cleanup behavior across all container types.

tests/addons/test_addon.py (3)

846-846: LGTM: Container cleanup includes volume removal

The test correctly verifies that container removal during addon loading includes volume cleanup (v=True), consistent with the enhanced cleanup behavior.


855-867: LGTM: Updated tests for Docker CLI command execution

The test assertions have been correctly updated to verify Docker CLI command execution instead of Docker SDK calls. The use of is_in_list helper ensures that the required arguments (--platform, --tag) are present in the correct order within the command list.


884-896: LGTM: Consistent CLI command testing for missing image case

The test properly verifies Docker CLI command execution for the missing image scenario, maintaining consistency with the refactored build process.

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

🧹 Nitpick comments (1)
tests/addons/test_addon.py (1)

970-981: Fix whitespace formatting issue in list slicing.

The helper function logic is correct, but there's a formatting issue that needs to be addressed.

Apply this diff to fix the whitespace issue:

-            b = b[b.index(c) :]
+            b = b[b.index(c):]

The function correctly implements the logic to check if all elements of one list appear in another list in order, which is useful for verifying command argument order in the tests.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
Cache: Disabled due to data retention organization setting
Knowledge Base: Disabled due to data retention organization setting

📥 Commits

Reviewing files that changed from the base of the PR and between 5906f33 and 077e7d2.

📒 Files selected for processing (4)
  • supervisor/docker/addon.py (2 hunks)
  • supervisor/docker/homeassistant.py (0 hunks)
  • supervisor/docker/manager.py (4 hunks)
  • tests/addons/test_addon.py (4 hunks)
💤 Files with no reviewable changes (1)
  • supervisor/docker/homeassistant.py
🚧 Files skipped from review as they are similar to previous changes (2)
  • supervisor/docker/manager.py
  • supervisor/docker/addon.py
🧰 Additional context used
🪛 Flake8 (7.2.0)
tests/addons/test_addon.py

[error] 978-978: whitespace before ':'

(E203)

⏰ Context from checks skipped due to timeout of 90000ms (5)
  • GitHub Check: Run tests Python 3.13.3
  • GitHub Check: Build armv7 supervisor
  • GitHub Check: Build i386 supervisor
  • GitHub Check: Build armhf supervisor
  • GitHub Check: Build aarch64 supervisor
🔇 Additional comments (3)
tests/addons/test_addon.py (3)

846-846: LGTM! Container removal now includes volume cleanup.

The addition of v=True correctly reflects the new behavior where volumes are also removed when containers are removed, aligning with the Docker CLI approach.


855-867: LGTM! Test correctly verifies the new Docker CLI command approach.

The updated assertions properly verify that the build process now uses run_command with the correct Docker CLI arguments, including platform specification and image tag.


884-896: LGTM! Consistent test updates for missing image scenario.

The test updates follow the same pattern as the previous test, correctly verifying the Docker CLI command construction for the missing image case.

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

🧹 Nitpick comments (1)
tests/addons/test_addon.py (1)

988-999: Fix whitespace formatting issue.

The helper function logic is correct, but there's a formatting issue flagged by static analysis.

Apply this diff to fix the whitespace issue:

-            b = b[b.index(c) :]
+            b = b[b.index(c):]
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
Cache: Disabled due to data retention organization setting
Knowledge Base: Disabled due to data retention organization setting

📥 Commits

Reviewing files that changed from the base of the PR and between 077e7d2 and 405941d.

📒 Files selected for processing (4)
  • supervisor/addons/build.py (1 hunks)
  • tests/addons/test_addon.py (5 hunks)
  • tests/api/test_addons.py (2 hunks)
  • tests/conftest.py (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (3)
  • tests/api/test_addons.py
  • tests/conftest.py
  • supervisor/addons/build.py
🧰 Additional context used
🪛 Flake8 (7.2.0)
tests/addons/test_addon.py

[error] 996-996: whitespace before ':'

(E203)

⏰ Context from checks skipped due to timeout of 90000ms (6)
  • GitHub Check: Build aarch64 supervisor
  • GitHub Check: Build i386 supervisor
  • GitHub Check: Build amd64 supervisor
  • GitHub Check: Build armhf supervisor
  • GitHub Check: Build armv7 supervisor
  • GitHub Check: Run tests Python 3.13.3
🔇 Additional comments (5)
tests/addons/test_addon.py (5)

21-21: LGTM: Import aligns with the architectural change.

The import of CommandReturn is consistent with the refactoring to use run_command which returns CommandReturn objects instead of directly using Docker SDK methods.


844-851: LGTM: Test mocking updated correctly for CLI approach.

The patching has been appropriately updated to mock coresys.docker.run_command instead of Docker SDK methods, consistent with the architectural change to use Docker CLI commands for building addons.


854-855: LGTM: Volume cleanup enhancement implemented.

The addition of v=True to container.remove() calls aligns with the PR objective to ensure anonymous and ephemeral volumes are properly cleaned up, preventing leftover volumes on the system.


866-878: LGTM: CLI command verification is thorough.

The assertions properly verify that the Docker CLI is invoked with the correct arguments including platform, tag, and version parameters. The use of is_in_list helper function ensures the command arguments maintain proper ordering.


892-914: LGTM: Consistent test pattern applied.

The same testing pattern for CLI commands is appropriately applied to the second test function, maintaining consistency across the test suite.

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

🧹 Nitpick comments (1)
tests/addons/test_addon.py (1)

988-999: Fix formatting issue in helper function.

The helper function logic is correct for checking ordered presence of elements, but there's a whitespace formatting issue flagged by static analysis.

Apply this diff to fix the formatting:

-            b = b[b.index(c) :]
+            b = b[b.index(c):]
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
Cache: Disabled due to data retention organization setting
Knowledge Base: Disabled due to data retention organization setting

📥 Commits

Reviewing files that changed from the base of the PR and between 405941d and 6ad5846.

📒 Files selected for processing (2)
  • tests/addons/test_addon.py (5 hunks)
  • tests/api/test_addons.py (2 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • tests/api/test_addons.py
🧰 Additional context used
🪛 Flake8 (7.2.0)
tests/addons/test_addon.py

[error] 996-996: whitespace before ':'

(E203)

⏰ Context from checks skipped due to timeout of 90000ms (5)
  • GitHub Check: Build amd64 supervisor
  • GitHub Check: Build aarch64 supervisor
  • GitHub Check: Build armv7 supervisor
  • GitHub Check: Build armhf supervisor
  • GitHub Check: Run tests Python 3.13.3
🔇 Additional comments (5)
tests/addons/test_addon.py (5)

21-21: Import addition looks good.

The new import for CommandReturn is correctly added to support the updated test mocking approach.


844-851: Test mocking updated appropriately for CLI command approach.

The test correctly switches from mocking images.build to run_command, returning a CommandReturn object that simulates successful Docker CLI execution. This aligns with the architectural change to use Docker BuildKit via CLI commands.


854-857: Container removal updated to include volume cleanup.

The addition of v=True to the container.remove call is consistent with the PR objective to ensure anonymous and ephemeral volumes are also removed, preventing leftover volumes on the system.


866-878: Docker CLI command verification is well-structured.

The assertions properly verify that the run_command method is called with correct Docker CLI arguments including platform specification and image tagging. The use of the is_in_list helper function ensures the command arguments are present in the expected order.


892-914: Consistent test pattern applied to second test function.

The test_addon_loads_missing_image function follows the same updated pattern as the first test, ensuring consistent verification of the Docker CLI command approach across both test scenarios.

@felipecrs
Copy link
Contributor Author

@coderabbitai this nitpick you mentioned is not correct. Ruff formatter actually prefers the other way.

@felipecrs
Copy link
Contributor Author

@agners I'm done with the changes. This PR is ready for review if you are ok with the approach.

I can also write a Home Assistant developer blog post for announcing this as well.

@felipecrs
Copy link
Contributor Author

I also attached a testing demonstration to the PR description.

@mdegat01
Copy link
Contributor

Can we add the image here:

def known_images(self) -> set[str]:
"""Return a set of all known images."""
return {
self.sys_homeassistant.image,
self.sys_supervisor.image or self.sys_supervisor.default_image,
*(plugin.image for plugin in self.sys_plugins.all_plugins if plugin.image),
*(addon.image for addon in self.sys_addons.installed if addon.image),
}

That way if the check happens to run while a build is in progress and sees the container it won't mark the system as unsupported. Looks good though, really like the idea.

@agners
Copy link
Member

agners commented Jun 26, 2025

Additionally, while I was on it, I resolved a few other nitpicks:

  1. docker.run_command only works with Detach=True, but was not including it in the default container.run args (i.e. was broken by default)

  2. docker_home_assistant_execute_command was executing using homeassistant:latest image because version arg was actually not being honored by docker.run_command.

  3. All container.remove() calls now include v=True. This will also delete whatever anonymous (and ephemeral) volumes that were created by that container like how docker run --rm does.

    • This avoids potential leftovers in the system depending on whether the image being executed had VOLUME instructions in its Dockerfile.

Nice finds 🤩 ! Can you make this drive-by changes separate PR(s)?

We'll likely have to iterate and test this PR a bit before it can go in. But these changes are rather small and can go in quickly. Also, it is better if these fixes are separate commits just in case we run into problems (bisect)/or have to revert.

@felipecrs
Copy link
Contributor Author

Absolutely, I'll work on all the requests. Thank you both.

@felipecrs felipecrs marked this pull request as draft June 27, 2025 02:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants