1
0
mirror of https://github.com/home-assistant/supervisor.git synced 2026-04-17 23:33:35 +01:00

Bugfix: No such file or directory: '/data/homeassistant/home-assistant_v2.db-shm' (#1795)

* Do not use `tar_file.add` to recursively add backup folder

As the folders might contain files which are being removed temporarily (e.g. shared memory file of sqlite database), relying on `tar_file.add` becomes problematic as it crashes the whole backup process if a file does not exist anymore.
This becomes annoying, if the file which causes the error should be excluded by the filter.

To workaround this issue, we manually iterating over the files/directories and apply filters before passing the file or directory to the `tar_file.add` method. As per [documentation](https://docs.python.org/3/library/pathlib.html#pure-paths), pure path does not access the file system.

Fixes #779

Signed-off-by: Maximilian Bösing <2189546+boesing@users.noreply.github.com>

* Remove unused import

Signed-off-by: Maximilian Bösing <2189546+boesing@users.noreply.github.com>

* Applied code review suggestions

Signed-off-by: Maximilian Bösing <2189546+boesing@users.noreply.github.com>

* Applied codestyle

Signed-off-by: Maximilian Bösing <2189546+boesing@users.noreply.github.com>

* Remove `pathlib` util and move `is_excluded_by_filter` into `tar` utils

Signed-off-by: Maximilian Bösing <2189546+boesing@users.noreply.github.com>

* Rename method

Signed-off-by: Maximilian Bösing <2189546+boesing@users.noreply.github.com>

* Rename `origin_dir` to `origin_path` and apply `Path` typehint

Signed-off-by: Maximilian Bösing <2189546+boesing@users.noreply.github.com>

* Codestyle

Signed-off-by: Maximilian Bösing <2189546+boesing@users.noreply.github.com>

* Add comment why we add the directory even if we are iterating over all its items

Signed-off-by: Maximilian Bösing <2189546+boesing@users.noreply.github.com>

* Use `atomic_contents_add` from tar utils to archive addon data

Signed-off-by: Maximilian Bösing <2189546+boesing@users.noreply.github.com>

* Remove unused function `exclude_filter`

Signed-off-by: Maximilian Bösing <2189546+boesing@users.noreply.github.com>

* Remove unsecure default list value

Signed-off-by: Maximilian Bösing <2189546+boesing@users.noreply.github.com>

* Some more codestyle

Signed-off-by: Maximilian Bösing <2189546+boesing@users.noreply.github.com>

* Lowercase method name `Path.joinpath`

Signed-off-by: Maximilian Bösing <2189546+boesing@users.noreply.github.com>

* Fix codestyle and use proper variable

Signed-off-by: Maximilian Bösing <2189546+boesing@users.noreply.github.com>

* Add test for `_is_excluded_by_filter`

Signed-off-by: Maximilian Bösing <2189546+boesing@users.noreply.github.com>

* Update addon.py

Co-authored-by: Pascal Vizeli <pascal.vizeli@syshack.ch>
This commit is contained in:
Maximilian Bösing
2020-06-26 11:36:49 +02:00
committed by GitHub
parent 3f31979f66
commit a3cf445c93
4 changed files with 73 additions and 41 deletions

View File

@@ -2,7 +2,8 @@
import attr
from supervisor.utils.tar import exclude_filter, secure_path
from pathlib import PurePath
from supervisor.utils.tar import secure_path, _is_excluded_by_filter
@attr.s
@@ -33,28 +34,29 @@ def test_not_secure_path():
assert [] == list(secure_path(test_list))
def test_exclude_filter_good():
def test_is_excluded_by_filter_good():
"""Test exclude filter."""
filter_funct = exclude_filter(["not/match", "/dev/xy"])
filter_list = ["not/match", "/dev/xy"]
test_list = [
TarInfo("test.txt"),
TarInfo("data/xy.blob"),
TarInfo("bla/blu/ble"),
TarInfo("data/../xy.blob"),
PurePath("test.txt"),
PurePath("data/xy.blob"),
PurePath("bla/blu/ble"),
PurePath("data/../xy.blob"),
]
assert test_list == [filter_funct(result) for result in test_list]
for path_object in test_list:
assert _is_excluded_by_filter(path_object, filter_list) is False
def test_exclude_filter_bad():
def test_is_exclude_by_filter_bad():
"""Test exclude filter."""
filter_funct = exclude_filter(["*.txt", "data/*", "bla/blu/ble"])
filter_list = ["*.txt", "data/*", "bla/blu/ble"]
test_list = [
TarInfo("test.txt"),
TarInfo("data/xy.blob"),
TarInfo("bla/blu/ble"),
TarInfo("data/test_files/kk.txt"),
PurePath("test.txt"),
PurePath("data/xy.blob"),
PurePath("bla/blu/ble"),
PurePath("data/test_files/kk.txt"),
]
for info in [filter_funct(result) for result in test_list]:
assert info is None
for path_object in test_list:
assert _is_excluded_by_filter(path_object, filter_list) is True