diff options
-rw-r--r-- | sos/plugins/foreman.py | 16 | ||||
-rw-r--r-- | sos/plugins/katello.py | 16 | ||||
-rw-r--r-- | sos/plugins/networking.py | 11 | ||||
-rw-r--r-- | sos/plugins/neutron.py | 172 | ||||
-rw-r--r-- | sos/plugins/openstack.py | 34 | ||||
-rw-r--r-- | sos/plugins/openstack_horizon.py | 74 | ||||
-rw-r--r-- | sos/plugins/openstack_keystone.py | 74 | ||||
-rw-r--r-- | sos/plugins/rpm.py | 5 | ||||
-rw-r--r-- | sos/utilities.py | 2 | ||||
-rw-r--r-- | tests/utilities_tests.py | 4 |
10 files changed, 365 insertions, 43 deletions
diff --git a/sos/plugins/foreman.py b/sos/plugins/foreman.py index be35ace0..60ec34df 100644 --- a/sos/plugins/foreman.py +++ b/sos/plugins/foreman.py @@ -1,3 +1,19 @@ +## Copyright (C) 2013 Red Hat, Inc., Lukas Zapletal <lzap@redhat.com> + +## This program is free software; you can redistribute it and/or modify +## it under the terms of the GNU General Public License as published by +## the Free Software Foundation; either version 2 of the License, or +## (at your option) any later version. + +## This program is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +## GNU General Public License for more details. + +## You should have received a copy of the GNU General Public License +## along with this program; if not, write to the Free Software +## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + import sos.plugintools import os diff --git a/sos/plugins/katello.py b/sos/plugins/katello.py index 68b32d64..54b30fac 100644 --- a/sos/plugins/katello.py +++ b/sos/plugins/katello.py @@ -1,3 +1,19 @@ +## Copyright (C) 2013 Red Hat, Inc., Lukas Zapletal <lzap@redhat.com> + +## This program is free software; you can redistribute it and/or modify +## it under the terms of the GNU General Public License as published by +## the Free Software Foundation; either version 2 of the License, or +## (at your option) any later version. + +## This program is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +## GNU General Public License for more details. + +## You should have received a copy of the GNU General Public License +## along with this program; if not, write to the Free Software +## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + import sos.plugintools import os diff --git a/sos/plugins/networking.py b/sos/plugins/networking.py index 90e1b58b..9724a4f6 100644 --- a/sos/plugins/networking.py +++ b/sos/plugins/networking.py @@ -111,12 +111,11 @@ class Networking(Plugin): self.add_cmd_output("ethtool -c "+eth) self.add_cmd_output("ethtool -g "+eth) - if os.path.exists("brctl"): - brctl_file=self.add_cmd_output("brctl show") - brctl_out=self.call_ext_prog("brctl show") - if brctl_out: - for br_name in self.get_bridge_name(brctl_out): - self.add_cmd_output("brctl showstp "+br_name) + brctl_file=self.add_cmd_output("brctl show") + brctl_out=self.call_ext_prog("brctl show") + if brctl_out: + for br_name in self.get_bridge_name(brctl_out): + self.add_cmd_output("brctl showstp "+br_name) if self.get_option("traceroute"): self.add_cmd_output("/bin/traceroute -n %s" % self.trace_host) diff --git a/sos/plugins/neutron.py b/sos/plugins/neutron.py new file mode 100644 index 00000000..03403227 --- /dev/null +++ b/sos/plugins/neutron.py @@ -0,0 +1,172 @@ +## Copyright (C) 2013 Red Hat, Inc., Brent Eagles <beagles@redhat.com> + +### This program is free software; you can redistribute it and/or modify +## it under the terms of the GNU General Public License as published by +## the Free Software Foundation; either version 2 of the License, or +## (at your option) any later version. + +## This program is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +## GNU General Public License for more details. + +## You should have received a copy of the GNU General Public License +## along with this program; if not, write to the Free Software +## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +import os +import re + +from sos.plugins import Plugin, RedHatPlugin, DebianPlugin, UbuntuPlugin + +# The Networking plugin includes most of what is needed from a snapshot +# of the networking, so we only need to focus on the parts that are specific +# to OpenStack Networking. The Process plugin should capture the dnsmasq +# command line. The libvirt plugin grabs the instance's XML definition which +# has the interface names for an instance. So what remains is relevant database +# info... + +class Neutron(Plugin): + """OpenStack Networking (quantum/neutron) related information + """ + plugin_name = "neutron" + + option_list = [("log", "Gathers all Neutron logs", "slow", False), + ("quantum", "Overrides checks for newer Neutron components", + "fast", False)] + + component_name = "neutron" + + def setup(self): + if os.path.exists("/etc/neutron/") and self.get_option("quantum", False): + self.component_name = self.plugin_name + else: + self.component_name = "quantum" + + self.add_copy_specs(["/etc/%s/" % self.component_name, + "/var/log/%s/" % self.component_name]) + + self.netns_dumps() + self.get_ovs_dumps() + + + def get_ovs_dumps(self): + # Check to see if we are using the Open vSwitch plugin. If not we + # should be able to skip the rest of the dump. + ovs_conf_check_out = self.call_ext_prog('grep "^core_plugin.*openvswitch" ' + + ("/etc/%s/*.conf" + self.component_name)) + + if not ovs_conf_check_out or len(ovs_conf_check_out[1].splitlines()) == 0: + return + + # The '-s' option enables dumping of packet counters on the + # ports. + self.add_cmd_output("ovs-dpctl -s show") + + # The '-t 5' adds an upper bound on how long to wait to connect + # to the Open vSwitch server, avoiding hangs when running sosreport. + self.add_cmd_output("ovs-vsctl -t 5 show") + + def netns_dumps(self): + # It would've been beautiful if we could get parts of the networking + # plugin to run in different namespaces. There are a couple of options + # in the short term: create a local instance and "borrow" some of the + # functionality, or simply copy some of the functionality. + prefixes = ["qdhcp", "qrouter"] + nslist = self.call_ext_prog("ip netns") + lease_directories = [] + if nslist: + for nsname in nslist[1].splitlines(): + prefix, netid = nsname.split('-', 1) + if len(netid) > 0 and prefix in prefixes: + self.ns_gather_data(nsname) + lease_directories.append("/var/lib/%s/dhcp/%s/" % + (self.component_name, netid)) + self.add_copy_specs(lease_directories) + + # TODO: Refactor! Copied from Networking plugin. + def get_interface_name(self,ip_addr_out): + """Return a dictionary for which key are interface name according to the + output of ifconifg-a stored in ifconfig_file. + """ + out={} + for line in ip_addr_out[1].splitlines(): + match=re.match('.*link/ether', line) + if match: + int=match.string.split(':')[1].lstrip() + out[int]=True + return out + + def ns_gather_data(self, nsname): + cmd_prefix = "ip netns exec %s " % nsname + self.add_cmd_output(cmd_prefix + "iptables-save") + self.add_cmd_output(cmd_prefix + "ifconfig -a") + self.add_cmd_output(cmd_prefix + "route -n") + # borrowed from networking plugin + ip_addr_out=self.call_ext_prog(cmd_prefix + "ip -o addr") + if ip_addr_out: + for eth in self.get_interface_name(ip_addr_out): + self.add_cmd_output(cmd_prefix + "ethtool "+eth) + self.add_cmd_output(cmd_prefix + "ethtool -i "+eth) + self.add_cmd_output(cmd_prefix + "ethtool -k "+eth) + self.add_cmd_output(cmd_prefix + "ethtool -S "+eth) + # Most, if not all, IFs in the namespaces are going to be + # virtual. The '-a', '-c' and '-g' options are not likely to be + # supported so these ops are not copied from the network + # plugin. + + # As all of the bridges are in the "global namespace", we do not need + # to gather info on them. + + def gen_pkg_tuple(self, packages): + names = [] + for p in packages: + names.append(p % { "comp" : self.component_name }) + return tuple(names) + +class DebianNeutron(Neutron, DebianPlugin, UbuntuPlugin): + """OpenStack Neutron related information for Debian based distributions + """ + package_list_template = ['%(comp)s-common', + '%(comp)s-plugin-cisco', + '%(comp)s-plugin-linuxbridge-agent', + '%(comp)s-plugin-nicira', + '%(comp)s-plugin-openvswitch', + '%(comp)s-plugin-openvswitch-agent', + '%(comp)s-plugin-ryu', + '%(comp)s-plugin-ryu-agent', + '%(comp)s-server', + 'python-%(comp)s', + 'python-%(comp)sclient'] + + def setup(self): + super(DebianNeutron, self).setup() + self.packages = self.gen_pkg_tuple(self.package_list_template) + self.add_copy_spec("/etc/sudoers.d/%s_sudoers" % self.component_name) + + + +class RedHatNeutron(Neutron, RedHatPlugin): + """OpenStack Neutron related information for Red Hat distributions + """ + + package_list_template = ['openstack-%(comp)s', + 'openstack-%(comp)s-linuxbridge' + 'openstack-%(comp)s-metaplugin', + 'openstack-%(comp)s-openvswitch', + 'openstack-%(comp)s-bigswitch', + 'openstack-%(comp)s-brocade', + 'openstack-%(comp)s-cisco', + 'openstack-%(comp)s-hyperv', + 'openstack-%(comp)s-midonet', + 'openstack-%(comp)s-nec' + 'openstack-%(comp)s-nicira', + 'openstack-%(comp)s-plumgrid', + 'openstack-%(comp)s-ryu', + 'python-%(comp)s', + 'python-%(comp)sclient'] + + def setup(self): + super(RedHatNeutron, self).setup() + self.packages = self.gen_pkg_tuple(self.package_list_template) + self.add_copy_specs(["/etc/sudoers.d/%s-rootwrap" % self.component_name]) diff --git a/sos/plugins/openstack.py b/sos/plugins/openstack.py index 21155f94..488fe6ce 100644 --- a/sos/plugins/openstack.py +++ b/sos/plugins/openstack.py @@ -56,26 +56,16 @@ class OpenStack(Plugin): self.add_copy_specs(["/etc/nova/", "/var/log/nova/"]) - # Keystone - self.add_copy_specs(["/etc/keystone/", - "/var/log/keystone/"]) - # Quantum self.add_copy_specs(["/etc/quantum/", "/var/log/quantum/"]) - def postproc(self): - self.do_file_sub('/etc/keystone/keystone.conf', - r"(admin_password\s*=\s*)(.*)", - r"\1******") - class DebianOpenStack(OpenStack, DebianPlugin, UbuntuPlugin): """OpenStack related information for Debian based distributions """ - packages = ('keystone', - 'melange', + packages = ('melange', 'nova-api-ec2', 'nova-api-metadata', 'nova-api-os-compute', @@ -94,25 +84,10 @@ class DebianOpenStack(OpenStack, DebianPlugin, UbuntuPlugin): 'nova-scheduler', 'nova-volume', 'novnc', - 'openstack-dashboard', - 'quantum-common', - 'quantum-plugin-cisco', - 'quantum-plugin-linuxbridge-agent', - 'quantum-plugin-nicira', - 'quantum-plugin-openvswitch', - 'quantum-plugin-openvswitch-agent', - 'quantum-plugin-ryu', - 'quantum-plugin-ryu-agent', - 'quantum-server', - 'python-django-horizon', - 'python-keystone', - 'python-keystoneclient', 'python-melange', 'python-nova', 'python-novaclient', 'python-novnc', - 'python-quantum', - 'python-quantumclient') def setup(self): # Nova @@ -127,14 +102,9 @@ class RedHatOpenStack(OpenStack, RedHatPlugin): """ packages = ('openstack-nova', - 'openstack-dashboard', - 'openstack-keystone', - 'openstack-quantum', 'python-nova', - 'python-keystoneclient', 'python-novaclient', - 'python-openstackclient', - 'python-quantumclient') + 'python-openstackclient') def setup(self): # Nova diff --git a/sos/plugins/openstack_horizon.py b/sos/plugins/openstack_horizon.py new file mode 100644 index 00000000..31ee5616 --- /dev/null +++ b/sos/plugins/openstack_horizon.py @@ -0,0 +1,74 @@ +## Copyright (C) 2009 Red Hat, Inc., Joey Boggs <jboggs@redhat.com> +## Copyright (C) 2012 Rackspace US, Inc., Justin Shepherd <jshepher@rackspace.com> +## Copyright (C) 2013 Red Hat, Inc., Jeremy Agee <jagee@redhat.com> + +### This program is free software; you can redistribute it and/or modify +## it under the terms of the GNU General Public License as published by +## the Free Software Foundation; either version 2 of the License, or +## (at your option) any later version. + +## This program is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +## GNU General Public License for more details. + +## You should have received a copy of the GNU General Public License +## along with this program; if not, write to the Free Software +## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +import os + +from sos.plugins import Plugin, RedHatPlugin, DebianPlugin, UbuntuPlugin + + +class OpenStackHorizon(Plugin): + """openstack horizon related information + """ + + plugin_name = "openstack-horizon" + option_list = [("log", "gathers openstack horizon logs", "slow", True)] + + def setup(self): + self.add_copy_specs(["/etc/openstack-dashboard/"]) + if self.option_enabled("log"): + self.add_copy_specs(["/var/log/horizon/"]) + + +class DebianOpenStackHorizon(OpenStackHorizon, DebianPlugin): + """OpenStack Horizon related information for Debian based distributions + """ + + packages = ('python-django-horizon', + 'openstack-dashboard', + 'openstack-dashboard-apache') + + def setup(self): + super(DebianOpenStackHorizon, self).setup() + self.add_copy_specs(["/etc/apache2/sites-available/"]) + + +class UbuntuOpenStackHorizon(OpenStackHorizon, UbuntuPlugin): + """OpenStack Horizon related information for Ubuntu based distributions + """ + + packages = ('python-django-horizon', + 'openstack-dashboard', + 'openstack-dashboard-ubuntu-theme') + + def setup(self): + super(UbuntuOpenStackHorizon, self).setup() + self.add_copy_specs(["/etc/apache2/conf.d/openstack-dashboard.conf"]) + + +class RedHatOpenStackHorizon(OpenStackHorizon, RedHatPlugin): + """OpenStack Horizon related information for Red Hat distributions + """ + + packages = ('python-django-horizon', + 'openstack-dashboard') + + def setup(self): + super(RedHatOpenStackHorizon, self).setup() + self.add_copy_specs(["/etc/httpd/conf.d/openstack-dashboard.conf"]) + if self.option_enabled("log"): + self.add_copy_specs(["/var/log/httpd/"]) diff --git a/sos/plugins/openstack_keystone.py b/sos/plugins/openstack_keystone.py new file mode 100644 index 00000000..96748d31 --- /dev/null +++ b/sos/plugins/openstack_keystone.py @@ -0,0 +1,74 @@ +## Copyright (C) 2013 Red Hat, Inc., Jeremy Agee <jagee@redhat.com> + +### This program is free software; you can redistribute it and/or modify +## it under the terms of the GNU General Public License as published by +## the Free Software Foundation; either version 2 of the License, or +## (at your option) any later version. + +## This program is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +## GNU General Public License for more details. + +## You should have received a copy of the GNU General Public License +## along with this program; if not, write to the Free Software +## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +import os + +from sos.plugins import Plugin, RedHatPlugin, DebianPlugin, UbuntuPlugin + + +class OpenStackKeystone(Plugin): + """openstack keystone related information + """ + plugin_name = "openstack-keystone" + + option_list = [("log", "gathers openstack keystone logs", "slow", True), + ("nopw", "dont gathers keystone passwords", "slow", True)] + + def setup(self): + self.add_copy_specs(["/etc/keystone/default_catalog.templates", + "/etc/keystone/keystone.conf", + "/etc/keystone/logging.conf", + "/etc/keystone/policy.json"]) + + if self.option_enabled("log"): + self.add_copy_specs(["/var/log/keystone/"]) + + def postproc(self): + if self.option_enabled("nopw"): + self.do_file_sub('/etc/keystone/keystone.conf', + r"(?m)^(admin_password.*=)(.*)", + r"\1 ******") + self.do_file_sub('/etc/keystone/keystone.conf', + r"(?m)^(admin_token.*=)(.*)", + r"\1 ******") + self.do_file_sub('/etc/keystone/keystone.conf', + r"(?m)^(connection.*=.*mysql://)(.*)(:)(.*)(@)(.*)", + r"\1\2:******@\6") + self.do_file_sub('/etc/keystone/keystone.conf', + r"(?m)^(password.*=)(.*)", + r"\1 ******") + self.do_file_sub('/etc/keystone/keystone.conf', + r"(?m)^(ca_password.*=)(.*)", + r"\1 ******") + + +class DebianOpenStackKeystone(OpenStackKeystone, DebianPlugin, UbuntuPlugin): + """OpenStack Keystone related information for Debian based distributions + """ + + packages = ('keystone', + 'python-keystone', + 'python-keystoneclient') + + +class RedHatOpenStackKeystone(OpenStackKeystone, RedHatPlugin): + """OpenStack Keystone related information for Red Hat distributions + """ + + packages = ('openstack-keystone', + 'python-keystone', + 'python-django-openstack-auth', + 'python-keystoneclient') diff --git a/sos/plugins/rpm.py b/sos/plugins/rpm.py index 71f36a0c..55c80196 100644 --- a/sos/plugins/rpm.py +++ b/sos/plugins/rpm.py @@ -24,7 +24,7 @@ class Rpm(Plugin, RedHatPlugin): ("rpmva", "runs a verify on all packages", "slow", False)] verify_list = [ - 'kernel', 'glibc', 'initscripts', + 'kernel$', 'glibc', 'initscripts', 'pam_.*', 'java.*', 'perl.*', 'rpm', 'yum', @@ -49,4 +49,7 @@ class Rpm(Plugin, RedHatPlugin): verify_list = map(pkgs_by_regex, self.verify_list) for pkg_list in verify_list: for pkg in pkg_list: + if 'debuginfo' in pkg \ + or pkg.endswith('-debuginfo-common'): + continue self.add_cmd_output("rpm -V %s" % pkg) diff --git a/sos/utilities.py b/sos/utilities.py index 4279b12e..fcc78c54 100644 --- a/sos/utilities.py +++ b/sos/utilities.py @@ -161,8 +161,6 @@ def sos_get_command_output(command, timeout=300): stdout=PIPE, stderr=STDOUT, bufsize=-1, env = cmd_env) stdout, stderr = p.communicate() - # hack to delete trailing '\n' added by p.communicate() - if stdout[-1:] == '\n': stdout = stdout[:-1] return (p.returncode, stdout, 0) else: return (127, "", 0) diff --git a/tests/utilities_tests.py b/tests/utilities_tests.py index 9cce51a4..fc9e858f 100644 --- a/tests/utilities_tests.py +++ b/tests/utilities_tests.py @@ -78,7 +78,7 @@ class ExecutableTest(unittest.TestCase): path = os.path.join(TEST_DIR, 'test_exe.py') ret, out, junk = sos_get_command_output(path) self.assertEquals(ret, 0) - self.assertEquals(out, "executed") + self.assertEquals(out, "executed\n") def test_output_non_exe(self): path = os.path.join(TEST_DIR, 'utility_tests.py') @@ -88,7 +88,7 @@ class ExecutableTest(unittest.TestCase): def test_shell_out(self): path = os.path.join(TEST_DIR, 'test_exe.py') - self.assertEquals("executed", shell_out(path)) + self.assertEquals("executed\n", shell_out(path)) class FindTest(unittest.TestCase): |