Blob Blame History Raw
From 3006f467e6e3908193d28d76bddcc372c4b98875 Mon Sep 17 00:00:00 2001
From: Pavel Moravec <pmoravec@redhat.com>
Date: Tue, 9 Jul 2019 13:35:28 +0200
Subject: [PATCH] [archive] Handle checking container sysroot in
 _make_leading_paths

Previously, in _make_leading_paths(), checking host file paths did not
account for non / sysroots, for situations where sos is run in a
container and the host's / is actually mounted under /host for example.
This would lead to copy errors when trying to copy symlinks.

This method now will use sysroot if one is set, thus avoiding copy
errors.

Resolves: #1705

Signed-off-by: Jake Hunsaker <jhunsake@redhat.com>
Signed-off-by: Pavel Moravec <pmoravec@redhat.com>
---
 sos/archive.py         | 17 +++++++++++++----
 sos/sosreport.py       |  4 ++--
 tests/archive_tests.py |  3 ++-
 3 files changed, 17 insertions(+), 7 deletions(-)

diff --git a/sos/archive.py b/sos/archive.py
index dcd6908d1..7ab36ce45 100644
--- a/sos/archive.py
+++ b/sos/archive.py
@@ -139,12 +139,13 @@ class FileCacheArchive(Archive):
     _archive_root = ""
     _archive_name = ""
 
-    def __init__(self, name, tmpdir, policy, threads, enc_opts):
+    def __init__(self, name, tmpdir, policy, threads, enc_opts, sysroot):
         self._name = name
         self._tmp_dir = tmpdir
         self._policy = policy
         self._threads = threads
         self.enc_opts = enc_opts
+        self.sysroot = sysroot
         self._archive_root = os.path.join(tmpdir, name)
         with self._path_lock:
             os.makedirs(self._archive_root, 0o700)
@@ -156,6 +157,13 @@ def dest_path(self, name):
             name = name.lstrip(os.sep)
         return (os.path.join(self._archive_root, name))
 
+    def join_sysroot(self, path):
+        if path.startswith(self.sysroot):
+            return path
+        if path[0] == os.sep:
+            path = path[1:]
+        return os.path.join(self.sysroot, path)
+
     def _make_leading_paths(self, src, mode=0o700):
         """Create leading path components
 
@@ -191,7 +199,8 @@ def in_archive(path):
             src_dir = src
         else:
             # Host file path
-            src_dir = src if os.path.isdir(src) else os.path.split(src)[0]
+            src_dir = (src if os.path.isdir(self.join_sysroot(src))
+                       else os.path.split(src)[0])
 
         # Build a list of path components in root-to-leaf order.
         path = src_dir
@@ -675,9 +684,9 @@ class TarFileArchive(FileCacheArchive):
     method = None
     _with_selinux_context = False
 
-    def __init__(self, name, tmpdir, policy, threads, enc_opts):
+    def __init__(self, name, tmpdir, policy, threads, enc_opts, sysroot):
         super(TarFileArchive, self).__init__(name, tmpdir, policy, threads,
-                                             enc_opts)
+                                             enc_opts, sysroot)
         self._suffix = "tar"
         self._archive_name = os.path.join(tmpdir, self.name())
 
diff --git a/sos/sosreport.py b/sos/sosreport.py
index cd61b6257..04cb86155 100644
--- a/sos/sosreport.py
+++ b/sos/sosreport.py
@@ -379,12 +379,12 @@ def _set_archive(self):
             auto_archive = self.policy.get_preferred_archive()
             self.archive = auto_archive(archive_name, self.tmpdir,
                                         self.policy, self.opts.threads,
-                                        enc_opts)
+                                        enc_opts, self.sysroot)
 
         else:
             self.archive = TarFileArchive(archive_name, self.tmpdir,
                                           self.policy, self.opts.threads,
-                                          enc_opts)
+                                          enc_opts, self.sysroot)
 
         self.archive.set_debug(True if self.opts.debug else False)
 
diff --git a/tests/archive_tests.py b/tests/archive_tests.py
index e5b329b5f..350220b92 100644
--- a/tests/archive_tests.py
+++ b/tests/archive_tests.py
@@ -20,7 +20,7 @@ class TarFileArchiveTest(unittest.TestCase):
     def setUp(self):
         self.tmpdir = tempfile.mkdtemp()
         enc = {'encrypt': False}
-        self.tf = TarFileArchive('test', self.tmpdir, Policy(), 1, enc)
+        self.tf = TarFileArchive('test', self.tmpdir, Policy(), 1, enc, '/')
 
     def tearDown(self):
         shutil.rmtree(self.tmpdir)
@@ -113,6 +113,7 @@ def test_make_link(self):
     def test_compress(self):
         self.tf.finalize("auto")
 
+
 if __name__ == "__main__":
     unittest.main()