From 3006f467e6e3908193d28d76bddcc372c4b98875 Mon Sep 17 00:00:00 2001 From: Pavel Moravec 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 Signed-off-by: Pavel Moravec --- 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()