530 Commits

Author SHA1 Message Date
Jan Čermák
9f3767b23d
Return cursor of the first host logs entry via headers (#5333)
* Return cursor of the first host logs entry via headers

Return first entry's cursor via custom `X-First-Cursor` header that can
be consumed by the client and used for continual requesting of the
historic logs. Once the first fetch returns data, the cursor can be
supplied as the first argument to the Range header in another call,
fetching accurate slice of the journal with the previous log entries
using the `Range: entries=cursor[[:num_skip]:num_entries]` syntax.

Let's say we fetch logs with the Range header `entries=:-19:20` (to
fetch very last 20 lines of the logs, see below why not
`entries:-20:20`) and we get `cursor50` as the reply (the actual value
will be much more complex and with no guaranteed format). To fetch
previous slice of the logs, we use `entries=cursor50:-20:20`, which
would return 20 lines previous to `cursor50` and `cursor30` in the
cursor header. This way we can go all the way back to the history.

One problem with the cursor is that it's not possible to determine when
the negative num_skip points beyond the first log entry. In that case
the client either needs to know what the first entry is (via
`entries=:0:1`) or can iterate naively and stop once two subsequent
requests return the same first cursor.

Another caveat, even though it's unlikely it will be hit in real usage,
is that it's not possible to fetch the last line only - if no cursor is
provided, negative num_skip argument is needed, and in that case we're
pointing one record back from the current cursor, which is the previous
record. The least we can return without knowing any cursor is thus
`entries=👎2` (where the `2` can be omitted, however with
`entries=👎1` we would lose the last line). This also explains why
different `num_skip` and `num_entries` must be used for the first fetch.

* Fix typo (fallback->callback)

* Refactor journal_logs_reader to always return the cursor

* Update tests for new cursor handling
2024-10-09 20:27:29 +02:00
Jan Čermák
e0d7985369
Fix number of lines returned with host logs' query argument (#5334)
If no cursor is specified and negative num_skip is used, we're pointing
one record back from the last one, so host logs always returned 101
lines as the default. This was also the case of the lines query argument
that used the number directly as num_skip. Instead of doing that, point
N-1 records to the back and then get N records. Handle 1 record and
invalid numbers silently to avoid the need for error handling in
unpractical edge cases.
2024-10-09 20:27:18 +02:00
Stefan Agner
2968a5717c
Update DNS plug-in on network change (#5331)
* Update DNS plug-in on network change

Restart the DNS plug-in when the primary network changes network
changes. This makes sure any potential host OS DNS configuration
changes get picked up by the DNS plug-in as well.

* Add a test case

---------

Co-authored-by: Mike Degatano <michael.degatano@gmail.com>
2024-10-09 20:16:36 +02:00
Stefan Agner
1ca22799d1
Improve WiFi settings error handling (#5293)
* Improve WiFi settings error handling

Currently, the frontend potentially provides no WiFi settings dictionary
but still tries to update other (IP address) settings on the interface.
This leads to a stack trace since network manager is not able to fetch
the WiFi settings from the settings dictionary. Simply fill out what
we can and let NetworkManager provide an error.

Also allow to disable a network interface which has no configuration.
This avoids an error when switching to auto and back to disabled then
press save on a new wireless network interface.

* Add debug message when already disabled

* Add pytest for incomplete WiFi settings as psoted by frontend

Simulate the frontend posting no WiFi settings. Make sure the Supervisor
handles this gracefully.
2024-09-11 17:53:36 +02:00
Stefan Agner
f5b996b66c
Make network API replace IP/WiFi settings (#5283)
* Allow to set user DNS through API with auto mode

Currently it is only possible to set DNS servers when in static mode.
However, there are use cases to set DNS servers when in auto mode as
well, e.g. if no local DNS server is provided by the DHCP, or the provided
DNS turns out to be non-working.

* Fix use separate data structure for IP configuration fallout

Make sure gateway is correctly converted to the internal IP
representation. Fix type info.

* Overwrite WiFi settings completely too

* Add test for DNS configuration

* Run ruff format

* ruff format

* Use schema validation as source for API defaults

Instead of using replace() simply set the API defaults in the API
schema.

* Revert "Use schema validation as source for API defaults"

This reverts commit 885506fd37395eb6cea9c787ee23349dac780b75.

* Use explicit dataclass initialization

This avoid the unnecessary replaces from before. It also makes it more
obvious that this part of the API doesn't patch existing settings.
2024-09-05 09:19:13 +02:00
Jan Čermák
05e0c7c3ab
Add "lines" and "verbose" query parameters for advanced logs (#5287)
Since headers are clumsy considering the Core proxy between the frontend
and Supervisor, add a way to adjust number of lines and verbose log
format using query parameters as well. If both query parameters and
headers are supplied, prefer the former, as it's more prominent when
reading through the request logs.
2024-09-04 16:11:37 +02:00
Stefan Agner
00d217b5f7
Make IPv4 and IPv6 parse errors raise an API error (#5282)
* Make IPv4 and IPv6 parse errors raise an API error

Currently, IP address parsing errors lead to an execption which is not
handled by the `api_validate()` call. By using concrete IPv4 and IPv6
types and `vol.Coerce()` parsing errors are properly handled.

* ruff format

* ruff check
2024-08-30 18:20:20 +02:00
Stefan Agner
c0e35376f3
Improve connection settings tests (#5278)
* Improve connection settings fixture

Make the connection settings fixture behave more closely to the actual
NetworkManager. The behavior has been tested with NetworkManager 1.42.4
(Debian 12) and 1.44.2 (HAOS 13.1). This likely behaves similar in older
versions too.

* Introduce separate skeleton and settings for wireless

Instead of having a combined network settings object which has
Ethernet and Wirless settings, create a separate settings object for
wireless.

* Handle addresses/address-data property like NetworkManager

* Address ruff check

* Improve network API test

Add a test which changes from "static" to "auto". Validate that settings
are updated accordingly. Specifically, today this does clear the DNS
setting (by not providing the property).

* ruff format

* ruff check

* Complete TEST_INTERFACE rename

* Add partial network update as test case
2024-08-30 16:07:04 +02:00
Mike Degatano
2be84e1282
Keep shared images on update (#5268)
* Test stub for keeping shared images after update

* Keep shared images on addon update

* ImageNotFound should only skip the one image not all

* Fix tests and nonetype error

* Normalize logic between two cleanup methods
2024-08-30 15:29:13 +02:00
Mike Degatano
0177cd9528
Add manual_only option to addon boot config (#5272)
* Add manual_forced option to addon boot config

* Include client library in pull request template

* Add boot_config to api output so frontend can use it

* `manual_forced` to `manual_only`
2024-08-27 17:59:52 +02:00
Stefan Agner
695a23a454
Minimize D-Bus requirements for tests (#5265)
This PR minimizes the D-Bus requirements for tests. It does this by
using dbus-daemon directly instead of dbus-launch. The latter is meant
for graphical applications and therefor has X11 dependencies. It also
leaves the D-Bus daemon running after the tests are done. This will
accumulate dbus-daemon processes over time which is not ideal.

I've also considered using dbus-run-session since it is meant to launch
processes with a private D-Bus session. For Python tests one could
launch it like so:
dbus-run-session -- python3 -m pytest ...

Then `DBUS_SESSION_BUS_ADDRESS` would be used automatically by the
`MessageBus` class. However, to keep the current behavior of the tests,
launching the D-Bus daemon manually is the better option.
2024-08-22 19:04:34 +02:00
dependabot[bot]
7366673eea
Bump sentry-sdk from 2.10.0 to 2.13.0 (#5246)
* Bump sentry-sdk from 2.10.0 to 2.13.0

Bumps [sentry-sdk](https://github.com/getsentry/sentry-python) from 2.10.0 to 2.13.0.
- [Release notes](https://github.com/getsentry/sentry-python/releases)
- [Changelog](https://github.com/getsentry/sentry-python/blob/master/CHANGELOG.md)
- [Commits](https://github.com/getsentry/sentry-python/compare/2.10.0...2.13.0)

---
updated-dependencies:
- dependency-name: sentry-sdk
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

* Replace deprecated apis with new ones

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Mike Degatano <michael.degatano@gmail.com>
2024-08-22 10:04:32 +02:00
Stefan Agner
1ba621be60
Use separate data structure for IP configuration (#5262)
* Use separate data structure for IP configuration

So far we use the same IpConfig data structure to represent the users
IP setting and the currently applied IP configuration.

This commit separates the two in IpConfig (for the currently applied
IP configuration) and IpSetting (representing the user provided IP
setting).

* Use custom string constants for connection settings

Use separate string constants for all connection settings. This makes
it easier to search where a particular NetworkManager connection
setting is used.

* Use Python typing for IpAddress in IpProperties

* Address pytest issue
2024-08-22 08:08:55 +02:00
Mike Degatano
986b92aee4
Keep shared images on addon uninstall (#5259)
* Keep shared images on addon uninstall

* Add missing step for mocking new addon in store
2024-08-21 11:14:57 +02:00
Stefan Agner
8ab396d77c
Improve and extend error handling on D-Bus connect (#5245)
* Improve and extend error handling on D-Bus connect

Avoid initializing the Supervisor board since it does not support the
Properties interface (see https://github.com/home-assistant/os-agent/issues/206).

This prevents the following somewhat confusing warning:
  No OS-Agent support on the host. Some Host functions have been disabled.

The OS Agent is actually installed on the host, it is just a single
object which caused issues. No functionalty was actually lost, as the
Supervisor board object has no features currently, and all other
interfaces got properly initialized still (thanks to gather()).

Print warnings more fine graned so it is clear which object exactly
causes an issue. Also print a log message on the lowest layer when an
error occures on calling D-Bus. This allows to easier track the actual
D-Bus error source.

Fixes: #5241

* Fix tests

* Use local variable

* Avoid stack trace when board support fails to load

* Fix tests

* Use override mechanism to disable Properties support

Instead of disable loading of Supervised entirly override initialization
to prevent loading the Properties interface.

* Revert "Fix tests"

This reverts commit 1e3c491ace2ebef60945c45573acd8d4464ea83e.
2024-08-20 17:55:53 +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
Mike Degatano
eb3986bea2
Allow core to mark addons as system managed (#5145)
* Allow core to mark addons as system managed

* System managed options only settable by Home Assistant
2024-08-13 15:14:42 +02:00
Mike Degatano
17ee234be4
Fix resp may be undefined end_backup issue (#5224) 2024-08-05 17:02:11 +02:00
Mike Degatano
0bbd15bfda
Restrict stopping core during migrations with force option (#5205) 2024-07-25 17:14:45 +02:00
Mike Degatano
591b9a4d87
Stop backup if pre backup failed in Core (#5203)
* Stop backup if pre backup failed in Core

* Fix API tests

* Partial backup in ci since there's no Home assistant

* Add ssl folder to partial backup

* Allow backups when Home Assistant is not running

* Undo change to skip db test
2024-07-25 17:08:43 +02:00
Mike Degatano
5ee7d16687
Add hard-coded image fallback for plugins for offline start (#5204) 2024-07-25 13:45:38 +02:00
Erik Montnemery
4ab4350c58
Add support for offline DB migration (#5202)
* Add support for offline DB migration

* Format code
2024-07-23 15:27:16 -04:00
Mike Degatano
49bc0624af
Ignore dns-data field in network settings update (#5147) 2024-06-24 15:47:58 -04:00
Pascal Vizeli
c37b5effd7
Add music assistant to the builtin repositories (#5128)
* Add music assistant to the builtin repositories

* Fix tests

* Fix tests some more

---------

Co-authored-by: Stefan Agner <stefan@agner.ch>
2024-06-21 12:17:21 +02:00
Mike Degatano
1bb814b793
Home Assistant watchdog attempts safe mode after max fails (#5124)
* Home Assistant watchdog attempts safe mode after max fails

* Remove duplicate line

* Refactor and logging change from feedback

* Update supervisor/misc/tasks.py

* Fix log text check in test

---------

Co-authored-by: Stefan Agner <stefan@agner.ch>
2024-06-20 21:50:29 +02:00
Mike Degatano
ab78d87304
Add safe mode option to core rebuild (#5120)
* Add safe mode option to core rebuild

* Adding logging for increased traceability
2024-06-05 15:44:07 -04:00
Mike Degatano
c4452a85b4
Fix addon in wrong state after restore (#5111)
* Fix addon in wrong state after restore

* Do not stop docker monitor for a shutdown
2024-06-04 16:17:43 +02:00
Mike Degatano
e57de4a3c1
Add uninstall addon suggestion to detached_addon_removed (#5105) 2024-06-03 10:38:34 -04:00
Mike Degatano
f150a19c0f
Create issue for detached addons (#5084)
* Create issue for detached addons

* Separate issues into missing and removed
2024-05-23 09:36:59 +02:00
Mike Degatano
eca99b69db
Max retries for auto applying addon image fixup (#5051)
* Max retries for auto applying addon image fixup

* Update supervisor/resolution/fixups/addon_execute_repair.py

Co-authored-by: Stefan Agner <stefan@agner.ch>

---------

Co-authored-by: Stefan Agner <stefan@agner.ch>
2024-05-22 11:54:02 +02:00
Mike Degatano
c0c0c4b7ad
Fix doc and changelog API response for orphaned addons (#5082)
* Fix doc and changelog API response for orphaned addons

* Use correct terminology in tests
2024-05-21 09:02:01 +02:00
Mike Degatano
c05984ca49
Fix no changelog API response (#5064)
* Fix no changelog API response

* Add comment reasoning HTTP 200 for no changelog

Co-authored-by: Stefan Agner <stefan@agner.ch>

* 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>
Co-authored-by: Stefan Agner <stefan@agner.ch>
2024-05-07 10:41:16 +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
Mike Degatano
8d18d2d9c6
Use signals to recognize new disks immediately (#5023)
* Use signals to recognize new disks immediately

* Add test for disabled data disk issue

* Add mock of UDisks2 base service to test

* Apply suggestions from code review

* Shutdown manager first to avoid potential race conditions

* Update tests/dbus_service_mocks/udisks2.py

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

---------

Co-authored-by: Stefan Agner <stefan@agner.ch>
Co-authored-by: Jan Čermák <sairon@users.noreply.github.com>
2024-04-22 16:35:03 +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
Mike Degatano
06513e88c6
Allow restarting core in safe mode (#5017) 2024-04-17 08:54:56 +02:00
Mike Degatano
dfd8fe84e0
Mount manager reload mounts all failed mounts (#5014)
* Mount manager reload mounts all failed mounts

* Remove invalid part of mount manager reload test
2024-04-12 12:02:29 +02:00
Mike Degatano
672a7621f9
Adopt a disabled data disk (#5010) 2024-04-11 13:53:19 -04:00
Mike Degatano
f0e2fb3f57
Addon load should not fail due to docker error (#5011) 2024-04-11 15:06:57 +02:00
Mike Degatano
50a2e8fde3
Allow adoption of existing data disk (#4991)
* Allow adoption of existing data disk

* Fix existing tests

* Add test cases and fix image issues

* Fix addon build test

* Run checks during setup not startup

* Addon load mimics plugin and HA load for docker part

* Default image accessible in except
2024-04-10 10:25:22 +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
Jan Čermák
906e400ab7
Fix submounts of /dev being read-only with Docker 25+ (#4997)
As described in #4996, Docker 25+ changes made sub-mounts of the /dev
filesystem to be mounted read-only. Revert to the previous behavior by
adjusting the ReadOnlyNonRecursive option. Cleaner way would be to
upstream support for setting this option via Mount class arguments, so
this change is meant to be rather a hotfix for the issue. Even better
approach would be mounting /dev non-recursively, and taking care of
creating all necessary filesystems when creating containers in
Supervisor.
2024-04-02 21:07:53 +02:00
Mike Degatano
90c971f9f1
Unsupported if wrong image used on virtualization (#4968)
* Unsupported if wrong image used on virtualization

* Add generic-aarch64 as supported image

* Add virtualization field to API

* Change startup to setup in check
2024-03-21 18:08:48 +01:00
Jan Čermák
0814552b2a
Use Journal Export Format for host (advanced) logs (#4963)
* Use Journal Export Format for host (advanced) logs

Add methods for handling Journal Export Format and use it for fetching
of host logs. This is foundation for colored streaming logs for other
endpoints as well.

* Make pylint happier - remove extra pass statement

* Rewrite journal gateway tests to mock ClientResponse's StreamReader

* Handle connection refused error when connecting to journal-gatewayd

* Use SYSTEMD_JOURNAL_GATEWAYD_SOCKET global path also for connection

* Use parsing algorithm suggested by @agners in review

* Fix timestamps in formatting, always use UTC for now

* Add tests for Accept header in host logs

* Apply suggestions from @agners

Co-authored-by: Stefan Agner <stefan@agner.ch>

* Bail out of parsing earlier if field is not in required fields

* Fix parsing issue discovered in the wild and add test case

* Make verbose formatter more tolerant

* Use some bytes' native functions for some minor optimizations

* Move MalformedBinaryEntryError to exceptions module, add test for it

---------

Co-authored-by: Stefan Agner <stefan@agner.ch>
2024-03-20 09:00:45 +01:00
Mike Degatano
0e0fadd72d
Fix some expected boot slot fields are optional (#4964)
* Fix some expected boot slot fields are optional

* Move stuff around to make pylint happy
2024-03-18 18:30:10 +01:00
Mike Degatano
a8af04ff82
Cache existence of addon paths (#4944)
* Cache existence of addon paths

* Always update submodules

* Switch to an always cached model

* Cache on store addon only

* Fix tests

* refresh_cache to refresh_path_cache

* Fix name change in test

* Move logic into StoreManager
2024-03-15 16:43:26 +01:00
Mike Degatano
2148de45a0
Allow client to change boot slot via API (#4945)
* Allow client to change boot slot via API

* Wrap call to rauc in job that checks for OS

* Reboot after changing the active boot slot

* Add test cases and clean up

* BootName to BootSlot

* Fix test

* Rename boot_name to boot_slot

* Fix tests after field change
2024-03-15 10:36:37 -04:00
Mike Degatano
9ca927dbe7
Watchdog does not start core before supervisor (#4955) 2024-03-13 09:08:27 +01:00
Mike Degatano
74a5899626
Remove discovery config validation from supervisor (#4937)
* Remove discovery config validation from supervisor

* Remove invalid test

* Change validation to require a dictionary for compatibility
2024-03-05 16:25:15 +01:00
Mike Degatano
202ebf6d4e
Set core timeout from S6_SERVICES_GRACETIME (#4938) 2024-03-04 11:14:51 -05:00