Skip to content
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

Update supervisor immediately on new version #5375

Merged
merged 2 commits into from
Oct 30, 2024

Conversation

mdegat01
Copy link
Contributor

@mdegat01 mdegat01 commented Oct 28, 2024

Proposed change

Attempt to update supervisor immediately if a new version is detected to prevent users from running into the "supervisor out of date" error on addon updates and such.

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

  • This PR fixes or closes issue: fixes #
  • This PR is related to issue:
  • Link to documentation pull request:
  • Link to cli pull request:
  • Link to client library pull request:

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

  • New Features

    • Introduced a new updater task that checks for and triggers updates for Home Assistant and Supervisor.
    • Added a configuration file for stable versions of software components, detailing versions and upgrade paths.
  • Bug Fixes

    • Enhanced the _update_supervisor method to limit execution to a single instance.
  • Tests

    • Improved test suite for scheduled tasks, including a new test for the updater triggering supervisor updates.

Copy link

coderabbitai bot commented Oct 28, 2024

📝 Walkthrough
📝 Walkthrough

Walkthrough

The changes include modifications to the Tasks class in supervisor/misc/tasks.py, adding a new method _reload_updater and updating the existing _update_supervisor method to include a limit parameter. A new JSON configuration file version_stable.json is introduced, detailing stable versions of various software components. Additionally, the test suite in tests/misc/test_tasks.py is enhanced for asynchronous testing, with updates to the return type of the fixture_tasks function and the addition of a new test for the _reload_updater method.

Changes

File Change Summary
supervisor/misc/tasks.py - Added method: async def _reload_updater(self) -> None
- Updated method signature: _update_supervisor(self) to _update_supervisor(self, limit=JobExecutionLimit.ONCE)
tests/fixtures/version_stable.json - New JSON file added with configuration details for software components, including channel, supervisor, homeassistant, hassos, hassos-upgrade, ota, cli, dns, audio, multicast, observer, image, and images.
tests/misc/test_tasks.py - Updated method signature: fixture_tasks(...) -> Tasks to fixture_tasks(...) -> AsyncGenerator[Tasks]
- Added method: async def test_reload_updater_triggers_supervisor_update(...)

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant Tasks
    participant Supervisor

    User->>Tasks: Trigger _reload_updater()
    Tasks->>Supervisor: Check for new versions
    alt New version available
        Tasks->>Supervisor: Trigger update
        Supervisor-->>Tasks: Update successful
    else No new version
        Supervisor-->>Tasks: No update needed
    end
Loading

Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ 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.
    • Generate unit testing code for this file.
    • 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 generate unit testing code for this file.
    • @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 generate unit testing code.
    • @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.

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

@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

🧹 Outside diff range and nitpick comments (3)
tests/misc/test_tasks.py (1)

172-210: Consider enhancing test coverage.

While the current test cases cover the happy path well, consider adding:

  1. Error scenarios (e.g., network failures during version check)
  2. Edge cases using pytest.mark.parametrize for different version combinations

Example structure:

@pytest.mark.parametrize(
    "current_version,new_version,should_update",
    [
        ("2024.10.0", "2024.10.1", True),
        ("2024.10.0", "2024.10.0", False),
        ("2024.10.1", "2024.10.0", False),  # Downgrade scenario
    ],
)
async def test_reload_updater_version_scenarios(
    tasks, coresys, current_version, new_version, should_update
):
    # Test implementation
supervisor/misc/tasks.py (2)

338-345: Consider enhancing the update process with logging and rate limiting.

While the implementation correctly checks for updates and triggers immediate supervisor updates, consider these improvements:

  1. Add logging when a new version is detected to help with troubleshooting
  2. Consider adding rate limiting to prevent too frequent update checks
  3. Add error handling for the update process

Here's a suggested enhancement:

 @Job(name="tasks_reload_updater")
 async def _reload_updater(self) -> None:
     """Check for new versions of Home Assistant, Supervisor, OS, etc."""
     await self.sys_updater.reload()
 
     # If there's a new version of supervisor, start update immediately
     if self.sys_supervisor.need_update:
+        _LOGGER.info(
+            "New supervisor version %s detected, triggering immediate update",
+            self.sys_supervisor.latest_version
+        )
         await self._update_supervisor()

337-345: Architecture Review: Well-integrated immediate update feature.

The implementation successfully achieves the PR's objective of immediate supervisor updates while maintaining system stability through:

  1. Thread-safe execution using JobExecutionLimit
  2. Integration with existing update check mechanisms
  3. Clear separation of concerns between update checking and execution

Consider documenting this behavior change in the supervisor's documentation to inform users about immediate updates.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between 8f2269d and ef325c0.

📒 Files selected for processing (3)
  • supervisor/misc/tasks.py (3 hunks)
  • tests/fixtures/version_stable.json (1 hunks)
  • tests/misc/test_tasks.py (2 hunks)
🔇 Additional comments (8)
tests/fixtures/version_stable.json (5)

1-3: LGTM! Basic configuration looks good.

The channel and supervisor version format follow semantic versioning (MAJOR.MINOR.PATCH).


50-60: Consider extending the upgrade path coverage.

The upgrade paths are defined from version 3 to 11, but there's no clear path for versions 12 and above. This might affect users trying to upgrade from these versions.

#!/bin/bash
# Search for any references to HassOS versions 12 and above
rg -g '!tests/' 'hassos.*1[2-9]' 

Consider:

  1. Adding upgrade paths for versions 12 and above if they exist
  2. Documenting the upgrade strategy for newer versions

61-66: Review the OTA URL pattern for security considerations.

The OTA URL uses HTTPS which is good, but we should verify that the domain is properly secured.

#!/bin/bash
# Search for any alternative OTA URL patterns or security configurations
rg -g '!tests/' 'os-artifacts\.home-assistant\.io'

67-84: Verify image repository consistency.

The image configuration correctly uses GHCR (GitHub Container Registry) for all components. The templating format using {arch} and {machine} is consistent across all entries.

#!/bin/bash
# Search for any image references to ensure all repositories are properly configured
rg -g '!tests/' 'ghcr\.io/home-assistant/.*-hassio-'

4-28: Verify platform coverage for Home Assistant versions.

All platforms are consistently set to version "2024.10.4". However, let's verify that no supported platforms are missing from this list.

tests/misc/test_tasks.py (2)

3-5: LGTM! Well-structured async test setup.

The changes to support async testing are well implemented:

  • Appropriate imports for async testing capabilities
  • Correct use of AsyncGenerator for proper resource management in the fixture
  • Clean integration with existing test infrastructure

Also applies to: 17-17, 25-27


172-210: LGTM! Well-structured test implementation.

The test thoroughly validates the supervisor update functionality with:

  • Proper system state initialization
  • Clean mocking of version checks
  • Clear test scenarios for both update and no-update cases
supervisor/misc/tasks.py (1)

13-13: LGTM: Import addition is appropriate.

The addition of JobExecutionLimit is necessary for controlling the execution frequency of the supervisor update task.

tests/fixtures/version_stable.json Show resolved Hide resolved
supervisor/misc/tasks.py Show resolved Hide resolved
Copy link

@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

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between ef325c0 and 09458f8.

📒 Files selected for processing (1)
  • supervisor/misc/tasks.py (4 hunks)
🔇 Additional comments (3)
supervisor/misc/tasks.py (3)

13-13: LGTM: Import addition for job execution limit.

The addition of JobExecutionLimit import is appropriate for implementing the concurrent execution control in supervisor updates.


69-69: LGTM: Task registration for updater reload.

The _reload_updater task is properly registered with a 2-hour interval, which is a reasonable frequency for version checks.


139-141: LGTM: Race condition prevention implemented.

The addition of JobExecutionLimit.ONCE effectively prevents concurrent supervisor updates, addressing the previously identified race condition concerns.

supervisor/misc/tasks.py Show resolved Hide resolved
@mdegat01 mdegat01 merged commit 9a07ff7 into main Oct 30, 2024
20 checks passed
@mdegat01 mdegat01 deleted the update-supervisor-immediately branch October 30, 2024 16:12
@github-actions github-actions bot locked and limited conversation to collaborators Nov 2, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants