Commit Graph

31 Commits

Author SHA1 Message Date
Mike Degatano
190b734332 Add progress reporting to addon, HA and Supervisor updates (#6195)
* Add progress reporting to addon, HA and Supervisor updates

* Fix assert in test

* Add progress to addon, core, supervisor updates/installs

* Fix double install bug in addons install

* Remove initial_install and re-arrange order of load
2025-10-07 16:54:11 +02:00
Jan Čermák
2e22e1e884 Add endpoint for complete logs of the latest container startup (#6163)
* Add endpoint for complete logs of the latest container startup

Add endpoint that returns complete logs of the latest startup of
container, which can be used for downloading Core logs in the frontend.

Realtime filtering header is used for the Journal API and StartedAt
parameter from the Docker API is used as the reference point. This means
that any other Range header is ignored for this parameter, yet the
"lines" query argument can be used to limit the number of lines. By
default "infinite" number of lines is returned.

Closes #6147

* Implement fallback for latest logs for OS older than 16.0

Implement fallback which uses the internal CONTAINER_LOG_EPOCH metadata
added to logs created by the Docker logger. Still prefer the time-based
method, as it has lower overhead and using public APIs.

* Address review comments

* Only use CONTAINER_LOG_EPOCH for latest logs

As pointed out in the review comments, we might not be able to get the
StartedAt for add-ons that are not running. Thus we need to use the only
reliable mechanism available now, which is the container log epoch.

* Remove dead code for 'Range: realtime' header handling
2025-09-16 11:29:28 +02:00
Stefan Agner
baf9695cf7 Refactoring around add-on store Repository classes (#5990)
* Rename repository fixture to test_repository

Also don't remove the built-in repositories. The list was incomplete,
and tests don't seem to require that anymore.

* Get rid of StoreType

The type doesn't have much value, we have constant strings anyways.

* Introduce types.py

* Use slug to determine which repository urls to return

* Simplify BuiltinRepository enum

* Mock GitRepo load

* Improve URL handling and repository creation logic

* Refactor update_repositories

* Get rid of get_from_url

It is no longer used in production code.

* More refactoring

* Address pylint

* Introduce is_git_based property to Repository class

Return all git based URLs, including the Core repository.

* Revert "Introduce is_git_based property to Repository class"

This reverts commit dfd5ad79bf.

* Fold type.py into const.py

Align more with how Supervisor code is typically structured.

* Update supervisor/store/__init__.py

Co-authored-by: Mike Degatano <michael.degatano@gmail.com>

* Apply repository remove suggestion

* Fix tests

---------

Co-authored-by: Mike Degatano <michael.degatano@gmail.com>
2025-07-10 11:07:53 +02:00
Mike Degatano
abc44946bb Refactor addon git repo (#5987)
* Refactor Repository into setup with inheritance

* Remove subclasses of GitRepo
2025-07-03 13:53:52 +02:00
Stefan Agner
b030879efd Rename detect-blocking-io API value to match other APIs (#5964)
* Rename detect-blocking-io API value to match other APIs

For the new detect-blocking-io option, use dashes instead of
underscores in `on-at-startup` for consistency with other API
endpoints.

This is a breaking change, but since the API is really new and not
really used yet, it is fairly safe to do so.

* Fix pytest
2025-06-20 12:52:12 +02:00
Stefan Agner
85f8107b60 Recreate aiohttp ClientSession after DNS plug-in load (#5862)
* Recreate aiohttp ClientSession after DNS plug-in load

Create a temporary ClientSession early in case we need to load version
information from the internet. This doesn't use the final DNS setup
and hence might fail to load in certain situations since we don't have
the fallback mechanims in place yet. But if the DNS container image
is present, we'll continue the setup and load the DNS plug-in. We then
can recreate the ClientSession such that it uses the DNS plug-in.

This works around an issue with aiodns, which today doesn't reload
`resolv.conf` automatically when it changes. This lead to Supervisor
using the initial `resolv.conf` as created by Docker. It meant that
we did not use the DNS plug-in (and its fallback capabilities) in
Supervisor. Also it meant that changes to the DNS setup at runtime
did not propagate to the aiohttp ClientSession (as observed in #5332).

* Mock aiohttp.ClientSession for all tests

Currently in several places pytest actually uses the aiohttp
ClientSession and reaches out to the internet. This is not ideal
for unit tests and should be avoided.

This creates several new fixtures to aid this effort: The `websession`
fixture simply returns a mocked aiohttp.ClientSession, which can be
used whenever a function is tested which needs the global websession.

A separate new fixture to mock the connectivity check named
`supervisor_internet` since this is often used through the Job
decorator which require INTERNET_SYSTEM.

And the `mock_update_data` uses the already existing update json
test data from the fixture directory instead of loading the data
from the internet.

* Log ClientSession nameserver information

When recreating the aiohttp ClientSession, log information what
nameservers exactly are going to be used.

* Refuse ClientSession initialization when API is available

Previous attempts to reinitialize the ClientSession have shown
use of the ClientSession after it was closed due to API requets
being handled in parallel to the reinitialization (see #5851).
Make sure this is not possible by refusing to reinitialize the
ClientSession when the API is available.

* Fix pytests

Also sure we don't create aiohttp ClientSession objects unnecessarily.

* Apply suggestions from code review

Co-authored-by: Jan Čermák <sairon@users.noreply.github.com>

---------

Co-authored-by: Jan Čermák <sairon@users.noreply.github.com>
2025-05-06 16:23:40 +02:00
Stefan Agner
5d07dd2c42 Add country to Supervisor info (#5826)
Similar to timezone also add country information to the Supervisor
info. This is useful to set country specific configurations such as
Wireless radio regulatory setting. This is also useful for add-ons
which need country information but only have hassio API access.
2025-04-22 16:18:23 +02:00
Jan Čermák
92cadb4c55 Fix /supervisor/reload after refactoring (#5791)
As discussed in [1], refactoring in #5759 changed signature of the
reload method and CLI now gets unexpected schema when `ha su reload` is
called. Change the method to return None as before and add a test for a
proper body content.

[1] https://github.com/home-assistant/supervisor/pull/5759/files#diff-1b4ed26f31e52ff5fe53efdc695eebacb1e46411f23cce58295591b2b20cd3faR238
2025-03-27 10:03:57 -04:00
Mike Degatano
80f7f07341 Add blockbuster option to API (#5746)
* Add blockbuster option to API

* cache not lru_cache
2025-03-25 09:40:43 +01:00
Mike Degatano
6ef4f3cc67 Add blockbuster library and find I/O from unit tests (#5731)
* Add blockbuster library and find I/O from unit tests

* Fix lint and test issue

* Fixes from feedback

* Avoid modifying webapp object in executor

* Split su options validation and only validate timezone on change
2025-03-06 16:40:13 -05:00
Mike Degatano
86133f8ecd Move read_text to executor (#5688)
* Move read_text to executor

* Fix issues found by coderabbit

* formated to formatted

* switch to async_capture_exception

* Find and replace got one too many

* Update patch mock to async_capture_exception

* Drop Sentry capture from format_message

The error handling got introduced in #2052, however, #2100 essentially
makes sure there will never be a byte object passed to this function.
And even if, the Sentry aiohttp plug-in will properly catch such an
exception.

---------

Co-authored-by: Stefan Agner <stefan@agner.ch>
2025-03-01 16:02:43 +01:00
Jan Čermák
cc9a931baa Fix Supervisor log fallback for the /follow endpoint (#5354)
When an error occurs when streaming Supervisor logs, the fallback method
receives the follow kwarg as well, which is invalid for the Docker log
handler:

 TypeError: APISupervisor.logs() got an unexpected keyword argument 'follow'

The exception is still printed to the logs but with all the extra noise
caused by this error. Removing the argument makes the stack trace more
comprehensible and the fallback actually works as desired.
2024-10-16 09:04:24 +02:00
Stefan Agner
f6faa18409 Bump pre-commit ruff to 0.5.7 and reformat (#5242)
It seems that the codebase is not formatted with the latest ruff
version. This PR reformats the codebase with ruff 0.5.7.
2024-08-13 20:53:56 +02:00
Jan Čermák
2a622a929d Limit reporting of errors in Supervisor logs fallback (#5040)
We do not need to capture HostNotSupported errors to Sentry. The only
possible code path this error might come from is where the Journal
Gateway Daemon socket is unavailable, which is already reported as an
"Unsupported system" repair.
2024-04-25 10:44:21 +02:00
Jan Čermák
18d9d32bca Fix Supervisor logs fallback (#5022)
Supervisor logs fallback in get_supervisor_logs didn't work properly
because the exception was caught in api_process_raw instead. This was
not discovered in tests because the side effect raised OSError, which
isn't handled there.

To address that, I split the advanced_logs to two functions, one being a
wrapped API handler, one being plain function returning response without
any additional error handling. The tests now check for both cases of
errors (HassioError and random generic Python error).

Refs #5021
2024-04-22 09:42:12 +02:00
Jan Čermák
a894c4589e Use Systemd Journal API for all logs endpoints in API (#4972)
* Use Systemd Journal API for all logs endpoints in API

Replace all logs endpoints using container logs with wrapped
advanced_logs function, adding possibility to get logs from previous
boots and following the logs. Supervisor logs are an excetion where
Docker logs are still used - in case an exception is raised while
accessing the Systemd logs, they're used as fallback - otherwise we
wouldn't have an easy way to see what went wrong.

* Refactor testing of advanced logs endpoints to a common method

* Send error while fetching Supervisor logs to Sentry; minor cleanup

* Properly handle errors and use consistent content type in logs endpoints

* Replace api_process_custom with reworked api_process_raw per @mdegat01 suggestion
2024-04-04 12:09:08 +02:00
Mike Degatano
7fd6dce55f Migrate to Ruff for lint and format (#4852)
* Migrate to Ruff for lint and format

* Fix pylint issues

* DBus property sets into normal awaitable methods

* Fix tests relying on separate tasks in connect

* Fixes from feedback
2024-02-05 11:37:39 -05:00
Stefan Agner
928aff342f Address pytest warnings (#4695) 2023-11-15 10:45:36 +01:00
Mike Degatano
c896b60410 Fix asyncio.wait in supervisor.reload (#4333)
* Fix asyncio.wait in supervisor.reload

* Unwrap to prevent throttling across tests
2023-06-01 18:38:42 -04:00
Mike Degatano
a6caccd845 Use session dbus mocks for all tests (#4198)
* Use session dbus mocks for all tests

* func instead of fn for pylint
2023-03-21 07:30:31 +01:00
Mike Degatano
14fcda5d78 Sentry only loaded when diagnostics on (#3993)
* Sentry only loaded when diagnostics on

* Logging when sentry is closed
2022-11-13 21:23:52 +01:00
Stefan Agner
2ebb405871 Add enhanced logging REST endpoints using systemd-journal-gatewayd (#3291)
* Add enhanced logging REST endpoints using systemd-journal-gatewayd

Add /host/logs/entries and /host/logs/{identifier}/entries to expose log
entries from systemd-journald running on the host. Use
systemd-journal-gatewayd which exposes the logs to the Supervisor via
Unix socket.

Current two query string parameters are allowed: "boot" and "follow".
The first will only return logs since last boot. The second will keep
the HTTP request open and send new log entries as they get added to the
systemd-journal.

* Allow Range header

Forward the Range header to systemd-journal-gatewayd. This allows to
select only a certain amount of log data. The Range header is a standard
header to select only partial amount of data. However, the "entries="
prefix is custom for systemd-journal-gatewayd, denoting that the numbers
following represent log entries (as opposed to bytes or other metrics).

* Avoid connecting if systemd-journal-gatewayd is not available

* Use path for all options

* Add pytests

* Address pylint issues

* Boot ID offsets and slug to identifier

* Fix tests

* API refactor from feedback

* fix tests and add identifiers

* stop isort and pylint fighting

* fix tests

* Update default log identifiers

* Only modify /host/logs endpoints

* Fix bad import

* Load log caches asynchronously at startup

* Allow task to complete in fixture

* Boot IDs and identifiers loaded on demand

* Add suggested identifiers

* Fix tests around boot ids

Co-authored-by: Mike Degatano <michael.degatano@gmail.com>
2022-10-13 11:40:11 -04:00
Mike Degatano
c0a409b25f No unpack variants for property sets (#3911) 2022-09-29 18:13:02 +02:00
Mike Degatano
c8f184f24c Add auto update option (#3769)
* Add update freeze option

* Freeze to auto update and plugin condition

* Add tests

* Add supervisor_version evaluation

* OS updates require supervisor up to date

* Run version check during startup
2022-08-15 12:13:22 -04:00
Mike Degatano
5f9b999a3c Use source instead of URL for repos (#3670) 2022-06-07 17:55:53 +02:00
Mike Degatano
ccd2c31390 Move repository urls to store settings file (#3665)
* Move repository urls to store settings file

* Remove default repos from supervisor config

* Fix clone at initial store load

* Mock git load in repository fixture
2022-06-07 10:02:21 +02:00
Mike Degatano
138fd7eec9 APIs for adding/removing an addon repository (#3649)
* APIs for adding/removing an addon repository

* Misunderstood addons.store, fixed usage
2022-05-23 09:16:42 +02:00
Pascal Vizeli
c3019bce7e Add Core Update API (#3413)
Co-authored-by: Paulus Schoutsen <balloob@gmail.com>
2022-01-24 10:32:23 +01:00
Joakim Sørensen
88490140af Add /supervisor/available_updates endpoint (#3300) 2021-11-17 09:28:46 +01:00
Pascal Vizeli
b59f741162 Validate secrets on options/validate UI check (#2854)
* Validate secrets on options/validate UI check

* Allow schema as payload

* Update supervisor/api/addons.py

Co-authored-by: Franck Nijhof <git@frenck.dev>

* Offload into a module

* using new function

* disable check

* fix options value

* generated return value

* add debug logging

Co-authored-by: Franck Nijhof <git@frenck.dev>
2021-05-10 14:27:50 +02:00
Pascal Vizeli
82f76f60bd Force / Enforce security if service is not available (#2744)
* Force / Enforce security if service is not available

* add options

* Add tests

* force security on test

* force security add-on validation

* Adjust style like codenotary

* Different exception type for backend error

* Adjust messages

* add comments

* ditch, not needed

* Address comment

* fix build
2021-03-24 14:36:23 +01:00