From 333918cba972db00d524074491593a2b080a153c Mon Sep 17 00:00:00 2001 From: Jake Hunsaker Date: Sun, 24 Dec 2017 13:04:44 -0500 Subject: [sosreport] Allow policies to change report name generation This changes the way sos generates the name for the final archive. Policies may now control the naming pattern by changing the new 'name_pattern' attribute. By default, this is set to 'legacy' for all policies, and maintains the naming pattern that sos has used up until this point. A policy may also set name_pattern to 'friendly' which will result in a more user-friendly name for the archive. Additionally, a policy may set name_pattern to a format() parsable string to explicitly set how the tarball should be named. Additionally, this removes the prompt for a 'customer name' on the report when running interactively. Instead, the short hostname of the system is now always used in place of the 'customer name'. A new option, --label, has been added (and which --name will now map to) which if provided will append a user-given string to the archive name after the hostname. This also sets the Red Hat policy to use the new 'friendly' pattern. Closes: #469 Resolves: #1175 Signed-off-by: Jake Hunsaker Signed-off-by: Bryn M. Reeves --- man/en/sosreport.1 | 9 ++++-- sos/policies/__init__.py | 72 ++++++++++++++++++++++++++++++++---------------- sos/policies/debian.py | 2 -- sos/policies/redhat.py | 2 +- sos/policies/suse.py | 1 - sos/sosreport.py | 16 ++++++----- 6 files changed, 66 insertions(+), 36 deletions(-) diff --git a/man/en/sosreport.1 b/man/en/sosreport.1 index be7afd65..8ec70c7e 100644 --- a/man/en/sosreport.1 +++ b/man/en/sosreport.1 @@ -11,7 +11,7 @@ sosreport \- Collect and package diagnostic and support data [-k plug.opt|--plugin-option plug.opt]\fR [--no-report] [--config-file conf]\fR [--batch] [--build] [--debug]\fR - [--name name] [--case-id id] [--ticket-number nr] + [--label label] [--case-id id] [--ticket-number nr] [-s|--sysroot SYSROOT]\fR [-c|--chroot {auto|always|never}\fR [--tmp-dir directory]\fR @@ -124,7 +124,12 @@ Override the default compression type specified by the active policy. Generate archive without prompting for interactive input. .TP .B \--name NAME -Specify a name to be used for the archive. +Deprecated. See \--label +.TP +.B \--label LABEL +Specify an arbitrary identifier to associate with the archive. +Labels will be appended after the system's short hostname and may contain +alphanumeric characters. .TP .B \--case-id NUMBER Specify a case identifier to associate with the archive. diff --git a/sos/policies/__init__.py b/sos/policies/__init__.py index 559e4fbe..5bdc7d85 100644 --- a/sos/policies/__init__.py +++ b/sos/policies/__init__.py @@ -6,6 +6,8 @@ import platform import time import fnmatch import tempfile +import random +import string from os import environ from sos.utilities import (ImporterHelper, @@ -201,6 +203,7 @@ No changes will be made to system configuration. vendor_text = "" PATH = "" default_scl_prefix = "" + name_pattern = 'legacy' _in_container = False _host_sysroot = '/' @@ -212,7 +215,6 @@ No changes will be made to system configuration. tests to construct PATH must call self.set_exec_path() after modifying PATH in their own initializer.""" self._parse_uname() - self.report_name = self.hostname self.case_id = None self.package_manager = PackageManager() self._valid_subclasses = [] @@ -267,11 +269,53 @@ No changes will be made to system configuration. """ This function should return the filename of the archive without the extension. + + This uses the policy's name_pattern attribute to determine the name. + There are two pre-defined naming patterns - 'legacy' and 'friendly' + that give names like the following: + + legacy - 'sosreport-tux.123456-20171224185433' + friendly - 'sosreport-tux-mylabel-123456-2017-12-24-ezcfcop.tar.xz' + + A custom name_pattern can be used by a policy provided that it + defines name_pattern using a format() style string substitution. + + Usable substitutions are: + + name - the short hostname of the system + label - the label given by --label + case - the case id given by --case-id or --ticker-number + rand - a random string of 7 alpha characters + + Note that if a datestamp is needed, the substring should be set + in the name_pattern in the format accepted by strftime(). + """ - if self.case_id: - self.report_name += "." + self.case_id - return "sosreport-%s-%s" % (self.report_name, - time.strftime("%Y%m%d%H%M%S")) + name = self.get_local_name().split('.')[0] + case = self.case_id + label = self.commons['cmdlineopts'].label + rand = ''.join(random.choice(string.lowercase) for x in range(7)) + + if self.name_pattern == 'legacy': + nstr = "sosreport-{name}{case}{date}" + case = '.' + case if case else '' + date = '-%Y%m%d%H%M%S' + elif self.name_pattern == 'friendly': + nstr = "sosreport-{name}{label}{case}{date}-{rand}" + case = '-' + case if case else '' + label = '-' + label if label else '' + date = '-%Y-%m-%d' + else: + nstr = self.name_pattern + + nstr = nstr.format( + name=name, + label=label, + case=case, + date=date, + rand=rand + ) + return time.strftime(nstr) def get_tmp_dir(self, opt_tmp_dir): if not opt_tmp_dir: @@ -461,9 +505,6 @@ class LinuxPolicy(Policy): """Returns the name usd in the pre_work step""" return self.host_name() - def sanitize_report_name(self, report_name): - return re.sub(r"[^-a-zA-Z.0-9]", "", report_name) - def sanitize_case_id(self, case_id): return re.sub(r"[^-a-z,A-Z.0-9]", "", case_id) @@ -471,16 +512,11 @@ class LinuxPolicy(Policy): # this method will be called before the gathering begins cmdline_opts = self.commons['cmdlineopts'] - customer_name = cmdline_opts.customer_name - localname = customer_name if customer_name else self.get_local_name() caseid = cmdline_opts.case_id if cmdline_opts.case_id else "" if not cmdline_opts.batch and not \ cmdline_opts.quiet: try: - self.report_name = input(_("Please enter your first initial " - "and last name [%s]: ") % localname) - self.case_id = input(_("Please enter the case id " "that you are generating this " "report for [%s]: ") % caseid) @@ -489,22 +525,12 @@ class LinuxPolicy(Policy): self._print() raise - if len(self.report_name) == 0: - self.report_name = localname - - if customer_name: - self.report_name = customer_name - if cmdline_opts.case_id: self.case_id = cmdline_opts.case_id - self.report_name = self.sanitize_report_name(self.report_name) if self.case_id: self.case_id = self.sanitize_case_id(self.case_id) - if (self.report_name == ""): - self.report_name = "default" - return diff --git a/sos/policies/debian.py b/sos/policies/debian.py index c2e0a2dd..15648d5d 100644 --- a/sos/policies/debian.py +++ b/sos/policies/debian.py @@ -8,7 +8,6 @@ class DebianPolicy(LinuxPolicy): distro = "Debian" vendor = "the Debian project" vendor_url = "http://www.debian.org/" - report_name = "" ticket_number = "" _debq_cmd = "dpkg-query -W -f='${Package}|${Version}\\n'" _debv_cmd = "dpkg --verify" @@ -19,7 +18,6 @@ class DebianPolicy(LinuxPolicy): def __init__(self, sysroot=None): super(DebianPolicy, self).__init__(sysroot=sysroot) - self.report_name = "" self.ticket_number = "" self.package_manager = PackageManager(query_command=self._debq_cmd, verify_command=self._debv_cmd, diff --git a/sos/policies/redhat.py b/sos/policies/redhat.py index df0b2f33..fcecd62e 100644 --- a/sos/policies/redhat.py +++ b/sos/policies/redhat.py @@ -45,10 +45,10 @@ class RedHatPolicy(LinuxPolicy): _in_container = False _host_sysroot = '/' default_scl_prefix = '/opt/rh' + name_pattern = 'friendly' def __init__(self, sysroot=None): super(RedHatPolicy, self).__init__(sysroot=sysroot) - self.report_name = "" self.ticket_number = "" # need to set _host_sysroot before PackageManager() if sysroot: diff --git a/sos/policies/suse.py b/sos/policies/suse.py index f99b56d6..71f70035 100644 --- a/sos/policies/suse.py +++ b/sos/policies/suse.py @@ -31,7 +31,6 @@ class SuSEPolicy(LinuxPolicy): def __init__(self, sysroot=None): super(SuSEPolicy, self).__init__() - self.report_name = "" self.ticket_number = "" self.package_manager = PackageManager( 'rpm -qa --queryformat "%{NAME}|%{VERSION}\\n"') diff --git a/sos/sosreport.py b/sos/sosreport.py index effd5034..36ea24a5 100644 --- a/sos/sosreport.py +++ b/sos/sosreport.py @@ -221,7 +221,7 @@ class SoSOptions(object): _quiet = False _debug = False _case_id = "" - _customer_name = "" + _label = "" _profiles = deque() _list_profiles = False _config_file = "" @@ -443,15 +443,15 @@ class SoSOptions(object): self._case_id = value @property - def customer_name(self): + def label(self): if self._options is not None: - return self._options.customer_name - return self._customer_name + return self._options.label + return self._label - @customer_name.setter - def customer_name(self, value): + @label.setter + def label(self, value): self._check_options_initialized() - self._customer_name = value + self._label = value @property def profiles(self): @@ -626,6 +626,8 @@ class SoSOptions(object): parser.add_argument("--name", action="store", dest="customer_name", help="specify report name") + parser.add_argument("--label", "--name", action="store", dest="label", + help="specify an additional report label") parser.add_argument("--config-file", action="store", dest="config_file", help="specify alternate configuration file") -- cgit