Repository: RedHatInsights/insights-core

Issue:
Traceback occurs when certain directories are corrupt in archive.
When files in an archive are corrupt and no stat information can be determined, a traceback occurs during hydration. Need to add a check for exceptions and continue.

```
$ insights-facts -y .
Traceback (most recent call last):
  File "/usr/bin/insights-facts", line 11, in <module>
    load_entry_point('insights-facts==1.0', 'console_scripts', 'insights-facts')()
  File "/usr/lib/python3.6/site-packages/insights_facts/__init__.py", line 223, in run
    ctx, broker = hydration.initialize_broker(args.archive, context=ctx)
  File "/usr/lib/python3.6/site-packages/insights/core/hydration.py", line 62, in initialize_broker
    ctx = create_context(path, context=context)
  File "/usr/lib/python3.6/site-packages/insights/core/hydration.py", line 52, in create_context
    all_files = list(get_all_files(path))
  File "/usr/lib/python3.6/site-packages/insights/core/hydration.py", line 18, in get_all_files
    for pth in get_all_files(ent.path):
  File "/usr/lib/python3.6/site-packages/insights/core/hydration.py", line 18, in get_all_files
    for pth in get_all_files(ent.path):
  File "/usr/lib/python3.6/site-packages/insights/core/hydration.py", line 18, in get_all_files
    for pth in get_all_files(ent.path):
  [Previous line repeated 1 more time]
  File "/usr/lib/python3.6/site-packages/insights/core/hydration.py", line 17, in get_all_files
    if ent.is_dir(follow_symlinks=False):
PermissionError: [Errno 13] Permission denied: './var/log/pcp/pmcd/pmcd.log.prev'


$ ll var/log/pcp/pmcd/
ls: cannot access var/log/pcp/pmcd/.: Permission denied
ls: cannot access var/log/pcp/pmcd/..: Permission denied
ls: cannot access var/log/pcp/pmcd/pmcd.log.prev: Permission denied
ls: cannot access var/log/pcp/pmcd/nfsclient.log: Permission denied
ls: cannot access var/log/pcp/pmcd/dm.log: Permission denied
ls: cannot access var/log/pcp/pmcd/root.log.prev: Permission denied
ls: cannot access var/log/pcp/pmcd/kvm.log: Permission denied
ls: cannot access var/log/pcp/pmcd/proc.log.prev: Permission denied
ls: cannot access var/log/pcp/pmcd/xfs.log.prev: Permission denied
ls: cannot access var/log/pcp/pmcd/linux.log.prev: Permission denied
ls: cannot access var/log/pcp/pmcd/nfsclient.log.prev: Permission denied
ls: cannot access var/log/pcp/pmcd/kvm.log.prev: Permission denied
ls: cannot access var/log/pcp/pmcd/dm.log.prev: Permission denied
ls: cannot access var/log/pcp/pmcd/pmcd.log: Permission denied
ls: cannot access var/log/pcp/pmcd/root.log: Permission denied
ls: cannot access var/log/pcp/pmcd/proc.log: Permission denied
ls: cannot access var/log/pcp/pmcd/xfs.log: Permission denied
ls: cannot access var/log/pcp/pmcd/linux.log: Permission denied
total 0
d????????? ? ? ? ?            ? .
d????????? ? ? ? ?            ? ..
?????????? ? ? ? ?            ? dm.log
?????????? ? ? ? ?            ? dm.log.prev
?????????? ? ? ? ?            ? kvm.log
?????????? ? ? ? ?            ? kvm.log.prev
?????????? ? ? ? ?            ? linux.log
?????????? ? ? ? ?            ? linux.log.prev
?????????? ? ? ? ?            ? nfsclient.log
?????????? ? ? ? ?            ? nfsclient.log.prev
?????????? ? ? ? ?            ? pmcd.log
?????????? ? ? ? ?            ? pmcd.log.prev
?????????? ? ? ? ?            ? proc.log
?????????? ? ? ? ?            ? proc.log.prev
?????????? ? ? ? ?            ? root.log
?????????? ? ? ? ?            ? root.log.prev
?????????? ? ? ? ?            ? xfs.log
?????????? ? ? ? ?            ? xfs.log.prev
```


Discussion:

Resolving patch:
diff --git a/insights/core/hydration.py b/insights/core/hydration.py
--- a/insights/core/hydration.py
+++ b/insights/core/hydration.py
@@ -14,11 +14,15 @@
     def get_all_files(path):
         with os.scandir(path) as it:
             for ent in it:
-                if ent.is_dir(follow_symlinks=False):
-                    for pth in get_all_files(ent.path):
-                        yield pth
-                elif ent.is_file(follow_symlinks=False):
-                    yield ent.path
+                try:
+                    if ent.is_dir(follow_symlinks=False):
+                        for pth in get_all_files(ent.path):
+                            yield pth
+                    elif ent.is_file(follow_symlinks=False):
+                        yield ent.path
+                except OSError as ex:
+                    log.exception(ex)
+
 
 else:
     def get_all_files(path):


Test patch:
diff --git a/insights/tests/core/test_hydration.py b/insights/tests/core/test_hydration.py
new file mode 100644
--- /dev/null
+++ b/insights/tests/core/test_hydration.py
@@ -0,0 +1,44 @@
+import pytest
+import sys
+import tempfile
+
+from insights.core.hydration import get_all_files
+from os import chmod, makedirs
+from os.path import join
+from shutil import rmtree
+
+
+def test_get_all_files():
+    tmp_dir = tempfile.mkdtemp()
+
+    d = join(tmp_dir, 'sys', 'kernel')
+    makedirs(d)
+    with open(join(d, 'kexec_crash_size'), "w") as f:
+        f.write("ohyeahbaby")
+
+    with open(join(d, 'kexec_loaded'), "w") as f:
+        f.write("1")
+
+    assert any(f.endswith("/sys/kernel/kexec_crash_size") for f in get_all_files(tmp_dir))
+
+    rmtree(tmp_dir, ignore_errors=True)
+
+
+@pytest.mark.skipif(sys.version_info < (3, 6), reason="This issue only occurs on python3+.")
+def test_get_all_files_oserror(caplog):
+    tmp_dir = tempfile.mkdtemp()
+
+    d = join(tmp_dir, 'sys', 'kernel')
+    makedirs(d)
+    with open(join(d, 'kexec_crash_size'), "w") as f:
+        f.write("ohyeahbaby")
+
+    chmod(d, 0o644)
+    chmod(join(tmp_dir, "sys"), 0o677)
+
+    any(f.endswith("/sys/kernel/kexec_crash_size") for f in get_all_files(tmp_dir))
+    assert "Errno 13" in caplog.text
+
+    chmod(join(tmp_dir, "sys"), 0o777)
+    chmod(d, 0o777)
+    rmtree(tmp_dir, ignore_errors=True)