diff options
author | Jake Hunsaker <jhunsake@redhat.com> | 2020-08-04 16:08:56 -0400 |
---|---|---|
committer | Jake Hunsaker <jhunsake@redhat.com> | 2020-08-14 12:39:08 -0400 |
commit | 51a5dbcb0df9ec8afa67cb5f1cfa0638276d302f (patch) | |
tree | da04722b2676c234abe3711276af65e403e0ae0c | |
parent | cc2c50ba0d42976a4e17c6f7d30bdd9a48aa3e06 (diff) | |
download | sos-51a5dbcb0df9ec8afa67cb5f1cfa0638276d302f.tar.gz |
[Plugin] Add method to tag files collected by generic copyspecs
Most of the files collected by sos are collected by 'generic' copyspecs,
such as those that target a parent directory and copy the contents
recursively. This makes it difficult to selectively add tags to files
copied from these copyspecs, without adding that tag to _every_ file
collected by it.
To alleviate this, add a new `add_file_tags()` method to `Plugin` that,
like `add_cmd_tags()` takes a dict of file name regex keys whose values
are the tag(s) to add to those files in the manifest.
Note that due to how file collection occurs, this tagging is done after
all collections are complete and any matches are added as _additional_
entries to the manifest, whose specification will be the regex used to
apply the tag.
Signed-off-by: Jake Hunsaker <jhunsake@redhat.com>
-rw-r--r-- | sos/report/plugins/__init__.py | 71 |
1 files changed, 61 insertions, 10 deletions
diff --git a/sos/report/plugins/__init__.py b/sos/report/plugins/__init__.py index ab0488b7..46fa7286 100644 --- a/sos/report/plugins/__init__.py +++ b/sos/report/plugins/__init__.py @@ -407,6 +407,7 @@ class Plugin(object): cmd_timeout = 300 _timeout_hit = False cmdtags = {} + filetags = {} # Default predicates predicate = None @@ -1017,6 +1018,56 @@ class Plugin(object): def _add_copy_paths(self, copy_paths): self.copy_paths.update(copy_paths) + def add_file_tags(self, tagdict): + """Apply a tag to a file matching a given regex, for use when a file + is copied by a more generic copyspec. + + :param tagdict: A dict containing the filepatterns to match and the + tag(s) to apply to those files + :type tagdict: ``dict`` + + `tagdict` takes the form `{file_pattern: tag}`, E.G. to match all bond + devices from /proc/net/bonding with the tag `bond`, use + `{'/proc/net/bonding/bond.*': ['bond']}` + """ + for fname in tagdict: + if isinstance(tagdict[fname], str): + tagdict[fname] = [tagdict[fname]] + self.filetags.update(tagdict) + + def get_tags_for_file(self, fname): + """Get the tags that should be associated with a file matching a given + regex + + :param fname: A regex for filenames to be matched against + :type fname: ``str`` + + :returns: The tag(s) associated with `fname` + :rtype: ``list`` of strings + """ + for key, val in self.filetags.items(): + if re.match(key, fname): + return val + return [] + + def generate_copyspec_tags(self): + """After file collections have completed, retroactively generate + manifest entries to apply tags to files copied by generic copyspecs + """ + for file_regex in self.filetags: + manifest_data = { + 'specification': file_regex, + 'files_copied': [], + 'tags': self.filetags[file_regex] + } + matched_files = [] + for cfile in self.copied_files: + if re.match(file_regex, cfile['srcpath']): + matched_files.append(cfile['dstpath']) + if matched_files: + manifest_data['files_copied'] = matched_files + self.manifest.files.append(manifest_data) + def add_copy_spec(self, copyspecs, sizelimit=None, maxage=None, tailit=True, pred=None, tags=[]): """Add a file or glob but limit it to sizelimit megabytes. Collect @@ -1100,10 +1151,9 @@ class Plugin(object): return False return True + _spec_tags = [] if len(files) == 1: _spec_tags = [get_filename_tag(files[0].split('/')[-1])] - else: - _spec_tags = [] _spec_tags.extend(tags) @@ -1279,21 +1329,21 @@ class Plugin(object): pred=pred, subdir=subdir, tags=tags, changes=changes, foreground=foreground) - def add_cmd_tags(self, cmddict): + def add_cmd_tags(self, tagdict): """Retroactively add tags to any commands that have been run by this plugin that match a given regex - :param cmddict: A dict containing the command regex and associated tags - :type cmddict: ``dict`` + :param tagdict: A dict containing the command regex and associated tags + :type tagdict: ``dict`` - `cmddict` takes the form of {cmd_regex: tags}, for example to tag all + `tagdict` takes the form of {cmd_regex: tags}, for example to tag all commands starting with `foo` with the tag `bar`, use {'foo.*': ['bar']} """ - for cmd in cmddict: - if isinstance(cmddict[cmd], str): - cmddict[cmd] = [cmddict[cmd]] - self.cmdtags = cmddict + for cmd in tagdict: + if isinstance(tagdict[cmd], str): + tagdict[cmd] = [tagdict[cmd]] + self.cmdtags.update(tagdict) def get_tags_for_cmd(self, cmd): """Get the tag(s) that should be associated with the given command @@ -1834,6 +1884,7 @@ class Plugin(object): for path in self.copy_paths: self._log_info("collecting path '%s'" % path) self._do_copy_path(path) + self.generate_copyspec_tags() def _collect_cmds(self): for soscmd in self.collect_cmds: |