diff options
-rw-r--r-- | sos/archive.py | 18 | ||||
-rw-r--r-- | sos/plugins/__init__.py | 7 | ||||
-rw-r--r-- | tests/plugin_tests.py | 12 |
3 files changed, 30 insertions, 7 deletions
diff --git a/sos/archive.py b/sos/archive.py index 2e42bbd0..60636251 100644 --- a/sos/archive.py +++ b/sos/archive.py @@ -98,6 +98,12 @@ class Archive(object): to be included in the generated archive.""" raise NotImplementedError + def name_max(self): + """Return the maximum file name length this archive can support. + This is the lesser of the name length limit of the archive + format and any temporary file system based cache.""" + raise NotImplementedError + def get_archive_path(self): """Return a string representing the path to the temporary archive. For archive classes that implement in-line handling @@ -206,6 +212,13 @@ class FileCacheArchive(Archive): def _makedirs(self, path, mode=0o700): os.makedirs(path, mode) + def name_max(self): + if 'PC_NAME_MAX' in os.pathconf_names: + pc_name_max = os.pathconf_names['PC_NAME_MAX'] + return os.pathconf(self._archive_root, pc_name_max) + else: + return 255 + def get_tmp_dir(self): return self._archive_root @@ -355,6 +368,11 @@ class TarFileArchive(FileCacheArchive): def name(self): return "%s.%s" % (self._name, self._suffix) + def name_max(self): + # GNU Tar format supports unlimited file name length. Just return + # the limit of the underlying FileCacheArchive. + return super(TarFileArchive, self).name_max() + def _build_archive(self): # python2.6 TarFile lacks the filter parameter if not six.PY3 and sys.version_info[1] < 7: diff --git a/sos/plugins/__init__.py b/sos/plugins/__init__.py index 3e391005..b2891444 100644 --- a/sos/plugins/__init__.py +++ b/sos/plugins/__init__.py @@ -42,11 +42,11 @@ def regex_findall(regex, fname): return [] -def _mangle_command(command): - # FIXME: this can be improved +def _mangle_command(command, name_max): mangledname = re.sub(r"^/(usr/|)(bin|sbin)/", "", command) mangledname = re.sub(r"[^\w\-\.\/]+", "_", mangledname) mangledname = re.sub(r"/", ".", mangledname).strip(" ._-") + mangledname = mangledname[0:name_max] return mangledname @@ -518,7 +518,8 @@ class Plugin(object): return grep(regexp, *fnames) def _mangle_command(self, exe): - return _mangle_command(exe) + name_max = self.archive.name_max() + return _mangle_command(exe, name_max) def _make_command_filename(self, exe): """The internal function to build up a filename based on a command.""" diff --git a/tests/plugin_tests.py b/tests/plugin_tests.py index 817e4f23..f73a003a 100644 --- a/tests/plugin_tests.py +++ b/tests/plugin_tests.py @@ -115,10 +115,14 @@ class PluginToolTests(unittest.TestCase): self.assertEquals(matches, []) def test_mangle_command(self): - self.assertEquals("foo", _mangle_command("/usr/bin/foo")) - self.assertEquals("foo_-x", _mangle_command("/usr/bin/foo -x")) - self.assertEquals("foo_--verbose", _mangle_command("/usr/bin/foo --verbose")) - self.assertEquals("foo_.path.to.stuff", _mangle_command("/usr/bin/foo /path/to/stuff")) + name_max = 255 + self.assertEquals("foo", _mangle_command("/usr/bin/foo", name_max)) + self.assertEquals("foo_-x", _mangle_command("/usr/bin/foo -x", name_max)) + self.assertEquals("foo_--verbose", _mangle_command("/usr/bin/foo --verbose", name_max)) + self.assertEquals("foo_.path.to.stuff", _mangle_command("/usr/bin/foo /path/to/stuff", name_max)) + longcmd ="foo is " + "a" * 256 + " long_command" + expected = longcmd[0:name_max].replace(' ', '_') + self.assertEquals(expected, _mangle_command(longcmd, name_max)) class PluginTests(unittest.TestCase): |