From 60a6c757ba5244e3bbff1fa125845233d0d4eb35 Mon Sep 17 00:00:00 2001 From: CentOS Sources Date: Oct 31 2019 07:47:12 +0000 Subject: import sos-collector-1.7-5.el7 --- diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..8766018 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +SOURCES/sos-collector-1.7.tar.gz diff --git a/.sos-collector.metadata b/.sos-collector.metadata new file mode 100644 index 0000000..76bf747 --- /dev/null +++ b/.sos-collector.metadata @@ -0,0 +1 @@ +5a4f3d843e90ac35af70c2da2e1b18a62df036c3 SOURCES/sos-collector-1.7.tar.gz diff --git a/SOURCES/sos-collector-nested-container-fix.patch b/SOURCES/sos-collector-nested-container-fix.patch new file mode 100644 index 0000000..0c33ae7 --- /dev/null +++ b/SOURCES/sos-collector-nested-container-fix.patch @@ -0,0 +1,59 @@ +From 0bc831a07be6ae837cb9029943c57255c47b647f Mon Sep 17 00:00:00 2001 +From: Jake Hunsaker +Date: Tue, 9 Apr 2019 12:59:03 -0400 +Subject: [PATCH] [sosnode] Don't create a container if we're in a container + +If sos-collector is being launched from a container on a containerized +host, we could potentially attempt to create a nested container. + +This change means we treat a sos-collector run that is already in a +container as a "normal" host and don't attempt the containerized bits. + +Signed-off-by: Jake Hunsaker +--- + soscollector/sosnode.py | 19 ++++++++++++++++++- + 1 file changed, 18 insertions(+), 1 deletion(-) + +diff --git a/soscollector/sosnode.py b/soscollector/sosnode.py +index a040244..405d05d 100644 +--- a/soscollector/sosnode.py ++++ b/soscollector/sosnode.py +@@ -68,10 +68,14 @@ class SosNode(): + self.connected = False + self.close_ssh_session() + return None ++ if self.local: ++ if self.check_in_container(): ++ self.host.containerized = False + self.log_debug("Host facts found to be %s" % + self.host.report_facts()) + self.get_hostname() +- self.create_sos_container() ++ if self.host.containerized: ++ self.create_sos_container() + self._load_sos_info() + + def _create_ssh_command(self): +@@ -84,6 +88,19 @@ class SosNode(): + return '{:<{}} : {}'.format(self._hostname, self.config['hostlen'] + 1, + msg) + ++ def check_in_container(self): ++ ''' ++ Tries to identify if we are currently running in a container or not. ++ ''' ++ if os.path.exists('/run/.containerenv'): ++ self.log_debug('Found /run/.containerenv. Running in container.') ++ return True ++ if os.environ.get('container') is not None: ++ self.log_debug("Found env var 'container'. Running in container") ++ return True ++ return False ++ ++ + def create_sos_container(self): + '''If the host is containerized, create the container we'll be using + ''' +-- +2.17.2 + diff --git a/SOURCES/sos-collector-none-cluster-fix.patch b/SOURCES/sos-collector-none-cluster-fix.patch new file mode 100644 index 0000000..8b7725e --- /dev/null +++ b/SOURCES/sos-collector-none-cluster-fix.patch @@ -0,0 +1,30 @@ +From a614ed8e5621f931d8ee76f1f59747a46144cb2d Mon Sep 17 00:00:00 2001 +From: Jake Hunsaker +Date: Thu, 4 Apr 2019 14:19:13 -0400 +Subject: [PATCH] [jbon] Fix typo in check_enabled() + +Fixes a typo in the check_enabled() method that could potentially +prevent sos-collector from correctly determining the cluster type on +python3 under certain circumstances. + +Signed-off-by: Jake Hunsaker +--- + soscollector/clusters/jbon.py | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/soscollector/clusters/jbon.py b/soscollector/clusters/jbon.py +index 28552ff..ea85ddf 100644 +--- a/soscollector/clusters/jbon.py ++++ b/soscollector/clusters/jbon.py +@@ -28,7 +28,7 @@ class jbon(Cluster): + def get_nodes(self): + return [] + +- def checK_enabled(self): ++ def check_enabled(self): + # This should never be called, but as insurance explicitly never + # allow this to be enabled via the determine_cluster() path + return False +-- +2.17.2 + diff --git a/SOURCES/sos-collector-old-pexpect.patch b/SOURCES/sos-collector-old-pexpect.patch new file mode 100644 index 0000000..93f5d92 --- /dev/null +++ b/SOURCES/sos-collector-old-pexpect.patch @@ -0,0 +1,24 @@ +diff --git a/soscollector/sosnode.py b/soscollector/sosnode.py +index 3aba0bf..ff130ba 100644 +--- a/soscollector/sosnode.py ++++ b/soscollector/sosnode.py +@@ -364,7 +364,9 @@ class SosNode(): + get_pty = True + if not self.local and not force_local: + cmd = "%s %s" % (self.ssh_cmd, quote(cmd)) +- res = pexpect.spawn(cmd, encoding='utf-8') ++ else: ++ cmd = "%s %s" % ('/bin/bash -c', quote(cmd)) ++ res = pexpect.spawn(cmd) + if need_root: + if self.config['need_sudo']: + res.sendline(self.config['sudo_pw']) +@@ -432,7 +434,7 @@ class SosNode(): + self.control_path, + self.config['ssh_user'], + self.address)) +- res = pexpect.spawn(cmd, encoding='utf-8') ++ res = pexpect.spawn(cmd) + + connect_expects = [ + u'Connected', diff --git a/SOURCES/sos-collector-rhcos-image.patch b/SOURCES/sos-collector-rhcos-image.patch new file mode 100644 index 0000000..2640115 --- /dev/null +++ b/SOURCES/sos-collector-rhcos-image.patch @@ -0,0 +1,29 @@ +From 6dafb42064b06a80720c6017e2576aea9a7211de Mon Sep 17 00:00:00 2001 +From: Jake Hunsaker +Date: Tue, 9 Apr 2019 13:00:44 -0400 +Subject: [PATCH] [redhat] Update RHCOS image + +Updates the image used by RHCOS nodes to be the rhel8 image instead +of rhel7. + +Signed-off-by: Jake Hunsaker +--- + soscollector/hosts/redhat.py | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/soscollector/hosts/redhat.py b/soscollector/hosts/redhat.py +index 33cec1f..774ecec 100644 +--- a/soscollector/hosts/redhat.py ++++ b/soscollector/hosts/redhat.py +@@ -66,7 +66,7 @@ class RedHatCoreOSHost(RedHatHost): + + containerized = True + container_runtime = 'podman' +- container_image = 'registry.redhat.io/rhel7/support-tools' ++ container_image = 'registry.redhat.io/rhel8/support-tools' + sos_path_strip = '/host' + + def check_enabled(self, rel_string): +-- +2.17.2 + diff --git a/SOURCES/sos-collector-rhhiv-profile.patch b/SOURCES/sos-collector-rhhiv-profile.patch new file mode 100644 index 0000000..8a65aa9 --- /dev/null +++ b/SOURCES/sos-collector-rhhiv-profile.patch @@ -0,0 +1,234 @@ +From fb8c2af36672b5868f504bae0704392f9e9b44a5 Mon Sep 17 00:00:00 2001 +From: Jake Hunsaker +Date: Fri, 12 Apr 2019 14:45:01 -0400 +Subject: [PATCH 1/3] [clusters] Add a cluster_name class member for better + identification + +Adds a cluster_name class member to Cluster() so that clusters may +specify a well-defined name beyond the name/acronym used to enable the +cluster manually. + +Signed-off-by: Jake Hunsaker +--- + soscollector/clusters/__init__.py | 9 +++++++++ + soscollector/sos_collector.py | 3 +-- + soscollector/sosnode.py | 1 - + 3 files changed, 10 insertions(+), 3 deletions(-) + +diff --git a/soscollector/clusters/__init__.py b/soscollector/clusters/__init__.py +index b9d2418..c1bd360 100644 +--- a/soscollector/clusters/__init__.py ++++ b/soscollector/clusters/__init__.py +@@ -26,6 +26,7 @@ class Cluster(object): + sos_plugins = [] + sos_plugin_options = {} + sos_preset = '' ++ cluster_name = None + + def __init__(self, config): + '''This is the class that cluster profile should subclass in order to +@@ -50,6 +51,14 @@ class Cluster(object): + self.options = [] + self._get_options() + ++ @classmethod ++ def name(cls): ++ '''Returns the cluster's name as a string. ++ ''' ++ if cls.cluster_name: ++ return cls.cluster_name ++ return cls.__name__.lower() ++ + def _get_options(self): + '''Loads the options defined by a cluster and sets the default value''' + for opt in self.option_list: +diff --git a/soscollector/sos_collector.py b/soscollector/sos_collector.py +index fee48ab..54410a2 100644 +--- a/soscollector/sos_collector.py ++++ b/soscollector/sos_collector.py +@@ -554,8 +554,7 @@ this utility or remote systems that it connects to. + break + + self.config['cluster'] = cluster +- name = str(cluster.__class__.__name__).lower() +- self.config['cluster_type'] = name ++ self.config['cluster_type'] = cluster.name() + self.log_info( + 'Cluster type set to %s' % self.config['cluster_type']) + break +diff --git a/soscollector/sosnode.py b/soscollector/sosnode.py +index 405d05d..3aba0bf 100644 +--- a/soscollector/sosnode.py ++++ b/soscollector/sosnode.py +@@ -100,7 +100,6 @@ class SosNode(): + return True + return False + +- + def create_sos_container(self): + '''If the host is containerized, create the container we'll be using + ''' +-- +2.17.2 + + +From 8d94e9ee9162c1b7676822958a94dfcd727d6dc8 Mon Sep 17 00:00:00 2001 +From: Jake Hunsaker +Date: Fri, 12 Apr 2019 14:47:31 -0400 +Subject: [PATCH 2/3] [clusters] Add cluster_name where appropriate + +Adds a cluster_name to a few of the existing cluster profiles. + +Signed-off-by: Jake Hunsaker +--- + soscollector/clusters/kubernetes.py | 1 + + soscollector/clusters/ovirt.py | 2 ++ + 2 files changed, 3 insertions(+) + +diff --git a/soscollector/clusters/kubernetes.py b/soscollector/clusters/kubernetes.py +index c5c2094..e18ee71 100644 +--- a/soscollector/clusters/kubernetes.py ++++ b/soscollector/clusters/kubernetes.py +@@ -52,6 +52,7 @@ class kubernetes(Cluster): + + class openshift(kubernetes): + ++ cluster_name = 'OpenShift Container Platform' + packages = ('atomic-openshift',) + sos_preset = 'ocp' + cmd = 'oc' +diff --git a/soscollector/clusters/ovirt.py b/soscollector/clusters/ovirt.py +index 0a074ca..18cbf2e 100644 +--- a/soscollector/clusters/ovirt.py ++++ b/soscollector/clusters/ovirt.py +@@ -23,6 +23,7 @@ from getpass import getpass + + class ovirt(Cluster): + ++ cluster_name = 'oVirt' + packages = ('ovirt-engine',) + + option_list = [ +@@ -122,6 +123,7 @@ class ovirt(Cluster): + + class rhv(ovirt): + ++ cluster_name = 'Red Hat Virtualization' + packages = ('rhevm', 'rhvm') + sos_preset = 'rhv' + +-- +2.17.2 + + +From 4606699e9a460ebd6345444ae915ff8384619ed3 Mon Sep 17 00:00:00 2001 +From: Jake Hunsaker +Date: Tue, 16 Apr 2019 15:41:33 -0400 +Subject: [PATCH 3/3] [ovirt] Add RHHI-V support + +Adds support for RHHI-V environments which are RHV environments that +also use the hypervisors as gluster nodes. The new 'rhhi_virt' cluster +profile will be enabled when sos-collector is run against an environment +that is _both_ RHV and has nodes listed in the 'gluster_server' table in +the RHV database. Note that this means if community oVirt is in use, the +gluster bits enabled by 'rhhi_virt' will not be enabled for the oVirt +cluster type. + +Included with this change is making DB queries more programmatic, and +making minor stylistic changes to the main query used by get_nodes() to +allow easier reading of the SQL query being built. + +Finally, remove an unused import of getpass. + +Resolves: #21 + +Signed-off-by: Jake Hunsaker +--- + soscollector/clusters/ovirt.py | 44 ++++++++++++++++++++++++++-------- + 1 file changed, 34 insertions(+), 10 deletions(-) + +diff --git a/soscollector/clusters/ovirt.py b/soscollector/clusters/ovirt.py +index 18cbf2e..8697d2e 100644 +--- a/soscollector/clusters/ovirt.py ++++ b/soscollector/clusters/ovirt.py +@@ -18,13 +18,13 @@ import fnmatch + + from pipes import quote + from soscollector.clusters import Cluster +-from getpass import getpass + + + class ovirt(Cluster): + +- cluster_name = 'oVirt' ++ cluster_name = 'Community oVirt' + packages = ('ovirt-engine',) ++ db_exec = '/usr/share/ovirt-engine/dbscripts/engine-psql.sh -c' + + option_list = [ + ('no-database', False, 'Do not collect a database dump'), +@@ -33,6 +33,14 @@ class ovirt(Cluster): + ('no-hypervisors', False, 'Do not collect from hypervisors') + ] + ++ def _run_db_query(self, query): ++ ''' ++ Wrapper for running DB queries on the master. Any scrubbing of the ++ query should be done _before_ passing the query to this method. ++ ''' ++ cmd = "%s %s" % (self.db_exec, quote(query)) ++ return self.exec_master_cmd(cmd, need_root=True) ++ + def _sql_scrub(self, val): + ''' + Manually sanitize SQL queries since we can't leave this up to the +@@ -58,18 +66,16 @@ class ovirt(Cluster): + def format_db_cmd(self): + cluster = self._sql_scrub(self.get_option('cluster')) + datacenter = self._sql_scrub(self.get_option('datacenter')) +- query = ("select host_name from vds_static where cluster_id in " +- "(select cluster_id from cluster where name like '%s'" +- " and storage_pool_id in (select id from storage_pool " +- "where name like '%s'))" % (cluster, datacenter)) +- self.dbcmd = ('/usr/share/ovirt-engine/dbscripts/engine-psql.sh ' +- '-c {}'.format(quote(query))) +- self.log_debug('Query command for ovirt DB set to: %s' % self.dbcmd) ++ self.dbquery = ("SELECT host_name from vds_static where cluster_id in " ++ "(select cluster_id FROM cluster WHERE name like '%s'" ++ " and storage_pool_id in (SELECT id FROM storage_pool " ++ "WHERE name like '%s'))" % (cluster, datacenter)) ++ self.log_debug('Query command for ovirt DB set to: %s' % self.dbquery) + + def get_nodes(self): + if self.get_option('no-hypervisors'): + return [] +- res = self.exec_master_cmd(self.dbcmd, need_root=True) ++ res = self._run_db_query(self.dbquery) + if res['status'] == 0: + nodes = res['stdout'].splitlines()[2:-1] + return [n.split('(')[0].strip() for n in nodes] +@@ -134,3 +140,21 @@ class rhv(ovirt): + return 'rhvh' + else: + return 'rhelh' ++ ++ ++class rhhi_virt(rhv): ++ ++ cluster_name = 'Red Hat Hyperconverged Infrastructure - Virtualization' ++ sos_plugins = ('gluster',) ++ sos_plugin_options = {'gluster.dump': 'on'} ++ sos_preset = 'rhv' ++ ++ def check_enabled(self): ++ return (self.master.is_installed('rhvm') and self._check_for_rhhiv()) ++ ++ def _check_for_rhhiv(self): ++ ret = self._run_db_query('SELECT count(server_id) FROM gluster_server') ++ if ret['status'] == 0: ++ # if there are any entries in this table, RHHI-V is in use ++ return ret['stdout'].splitlines()[2].strip() != '0' ++ return False +-- +2.17.2 + diff --git a/SOURCES/sos-collector-setuptools.patch b/SOURCES/sos-collector-setuptools.patch new file mode 100644 index 0000000..f661895 --- /dev/null +++ b/SOURCES/sos-collector-setuptools.patch @@ -0,0 +1,13 @@ +diff --git a/setup.py b/setup.py +index 407ff65..9399865 100644 +--- a/setup.py ++++ b/setup.py +@@ -23,6 +23,7 @@ setup( + packages=find_packages(), + scripts=['sos-collector'], + data_files=[ +- ('share/licenses/sos-collector', ['LICENSE']), ++ # Workaround setuptools difference between upstream & RHEL ++ # ('share/licenses/sos-collector', ['LICENSE']), + ('share/man/man1/', ['man/en/sos-collector.1']) + ]) diff --git a/SPECS/sos-collector.spec b/SPECS/sos-collector.spec new file mode 100644 index 0000000..4e4434c --- /dev/null +++ b/SPECS/sos-collector.spec @@ -0,0 +1,124 @@ +Summary: Capture sosreports from multiple nodes simultaneously +Name: sos-collector +Version: 1.7 +Release: 5%{?dist} +Source0: http://people.redhat.com/jhunsake/sos-collector/%{name}-%{version}.tar.gz +License: GPLv2 +BuildArch: noarch +Url: https://github.com/sosreport/sos-collector +Requires: sos >= 3.0 +Obsoletes: clustersos < 1.2.2-2 +Provides: clustersos = %{version}-%{release} + +Patch0: sos-collector-setuptools.patch +Patch1: sos-collector-old-pexpect.patch +Patch2: sos-collector-none-cluster-fix.patch +Patch3: sos-collector-nested-container-fix.patch +Patch4: sos-collector-rhcos-image.patch +Patch5: sos-collector-rhhiv-profile.patch + +%if 0%{?rhel} == 7 +BuildRequires: python-devel +BuildRequires: python-setuptools +Requires: python2-futures +Requires: python-six +Requires: pexpect +%else +BuildRequires: python3-devel +Requires: python3-six +Requires: python3-pexpect +%endif + + +%description +sos-collector is a utility designed to capture sosreports from multiple nodes +at once and collect them into a single archive. If the nodes are part of +a cluster, profiles can be used to configure how the sosreport command +is run on the nodes. + +%prep +%setup -q +%patch0 -p1 +%patch1 -p1 +%patch2 -p1 +%patch3 -p1 +%patch4 -p1 +%patch5 -p1 + +%build +%if 0%{?rhel} == 7 +%py2_build +%else +%py3_build +%endif + +%install +mkdir -p ${RPM_BUILD_ROOT}%{_mandir}/man1 +install -p -m644 man/en/sos-collector.1 ${RPM_BUILD_ROOT}%{_mandir}/man1/ +%if 0%{?rhel} == 7 +%py2_install +%else +%py3_install +%endif + + + +%check +%if 0%{?rhel} == 7 +%{__python2} setup.py test +%else +%{__python3} setup.py test +%endif + +%files +%{_bindir}/sos-collector +%if 0%{?rhel} == 7 +%{python2_sitelib}/* +%else +%{python3_sitelib}/* +%endif +%{_mandir}/man1/* + +%doc LICENSE + +%changelog +* Wed May 15 2019 Jake Hunsaker - 1.7-5 +- Add missing local fixes for older pexpect versions + +* Wed May 15 2019 Jake Hunsaker - 1.7-4 +- Correct handling of older pexpect versions + +* Tue Apr 23 2019 Jake Hunsaker - 1.7-3 +- Added RHHI-V cluster profile + +* Thu Apr 11 2019 Jake Hunsaker - 1.7-2 +- Fix 'none' cluster type enablement +- Update RHCOS image to use RHEL 8 support-tools +- Fix execution from within a container + +* Mon Apr 01 2019 Jake Hunsaker - 1.7-1 +- New upstream release +- Enhance container execution + +* Thu Mar 07 2019 Jake Hunsaker - 1.6-3 +- Fix local command execution +- Fix quoting for non-root commands +- Backport Satellite support +- Backport RHCOS support + +* Tue Dec 11 2018 Jake Hunsaker - 1.6-2 +- Handle older pexpect installations on RHEL 7 + +* Tue Dec 11 2018 Jake Hunsaker - 1.6-1 +- New upstream release +- Drop paramiko dependency, use OpenSSH ControlPersist instead. + +* Wed Nov 07 2018 Jake Hunsaker - 1.5-2 +- Fix cluster option reporting + +* Mon Oct 22 2018 Jake Hunsaker - 1.5-1 +- Update to version 1.5 +- Resolves CVE-2018-14650 + +* Wed Aug 01 2018 Jake Hunsaker 1.4-3 +- Initial RHEL 7 release