From ff00878ff13d3e38306cf05b3bd5dcda19a4cc7a Mon Sep 17 00:00:00 2001 From: Guido Günther Date: Tue, 10 Jun 2014 22:45:43 +0200 Subject: Remove unused imports --- whatmaps/command.py | 4 ---- 1 file changed, 4 deletions(-) diff --git a/whatmaps/command.py b/whatmaps/command.py index 3225f54..4ca730f 100755 --- a/whatmaps/command.py +++ b/whatmaps/command.py @@ -21,11 +21,7 @@ from __future__ import print_function import glob import os import logging -import re -import string -import subprocess import sys -import errno from optparse import OptionParser try: import lsb_release -- cgit v1.2.3 From ac817c1fc37bd7e831b33f32028005b612eb76eb Mon Sep 17 00:00:00 2001 From: Guido Günther Date: Tue, 10 Jun 2014 22:55:54 +0200 Subject: Print userfriendly message if not root Closes: #751088 --- whatmaps/command.py | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/whatmaps/command.py b/whatmaps/command.py index 4ca730f..2593398 100755 --- a/whatmaps/command.py +++ b/whatmaps/command.py @@ -22,6 +22,7 @@ import glob import os import logging import sys +import errno from optparse import OptionParser try: import lsb_release @@ -165,7 +166,14 @@ def main(argv): logging.debug(" %s", so) # Find processes that map them - restart_procs = check_maps(get_all_pids(), shared_objects) + try: + restart_procs = check_maps(get_all_pids(), shared_objects) + except IOError as e: + if e.errno == errno.EACCES: + logging.error("Can't open process maps in '/proc//maps', are you root?") + return 1 + else: + raise logging.debug("Processes that map them:") for exe, pids in restart_procs.items(): logging.debug(" Exe: %s Pids: %s", exe, pids), -- cgit v1.2.3 From e1b9e7fe3b1fa6b6e829f7eb5787b67d9894cfd1 Mon Sep 17 00:00:00 2001 From: Guido Günther Date: Fri, 2 May 2014 17:28:38 +0200 Subject: pkg_services: Check if a service is actually installed So far we returned the full list from pkg_services. This is o.k. for many to one mappings like apache but not for one to many like openjdk. To avoid to print out services that aren't installed check that beforehand. --- whatmaps/debiandistro.py | 10 ++++++++-- whatmaps/distro.py | 8 +++++++- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/whatmaps/debiandistro.py b/whatmaps/debiandistro.py index 4a3d0db..3a47d50 100644 --- a/whatmaps/debiandistro.py +++ b/whatmaps/debiandistro.py @@ -26,7 +26,7 @@ except ImportError: lsb_release = None import logging -import string +import os import subprocess import sys @@ -35,7 +35,7 @@ from . debianpkg import DebianPkg from . pkg import PkgError class DebianDistro(Distro): - "Debian (dpkg) based distribution""" + "Debian (dpkg) based distribution" id = 'Debian' _pkg_services = { 'apache2-mpm-worker': [ 'apache2' ], @@ -73,8 +73,14 @@ class DebianDistro(Distro): @classmethod def restart_service_cmd(klass, name): + """The command that should be used to start a service""" return ['invoke-rc.d', name, 'restart'] + @classmethod + def is_service_installed(klass, name): + """Whether the system has this service""" + return os.path.exists('/etc/init.d/%s' % name) + @classmethod def has_apt(klass): return True diff --git a/whatmaps/distro.py b/whatmaps/distro.py index e4f417f..5625955 100644 --- a/whatmaps/distro.py +++ b/whatmaps/distro.py @@ -48,13 +48,19 @@ class Distro(object): """Restart a service""" subprocess.call(klass.restart_service_cmd(service)) + @classmethod + def is_service_installed(klass, service): + """Check wether a service exists on the system""" + return True + @classmethod def pkg_services(klass, pkg): """ List of services that package pkg needs restarted that aren't part of pkg itself """ - return klass._pkg_services.get(pkg.name, []) + return [ s for s in klass._pkg_services.get(pkg.name, []) + if klass.is_service_installed(s) ] @classmethod def pkg_service_blacklist(klass, pkg): -- cgit v1.2.3 From e3338128a3e1489003e0334bf3e64efe337c53fc Mon Sep 17 00:00:00 2001 From: Guido Günther Date: Thu, 26 Jun 2014 09:37:25 +0200 Subject: Remove unused imports --- whatmaps/command.py | 7 +++---- whatmaps/debiandistro.py | 1 + whatmaps/redhatdistro.py | 1 - 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/whatmaps/command.py b/whatmaps/command.py index 2593398..e02b176 100755 --- a/whatmaps/command.py +++ b/whatmaps/command.py @@ -18,11 +18,12 @@ from __future__ import print_function +import errno import glob import os import logging +import subprocess import sys -import errno from optparse import OptionParser try: import lsb_release @@ -32,9 +33,7 @@ except ImportError: from . process import Process from . debiandistro import DebianDistro from . redhatdistro import FedoraDistro -from . pkg import Pkg, PkgError -from . debianpkg import DebianPkg -from . rpmpkg import RpmPkg +from . pkg import PkgError def check_maps(procs, shared_objects): diff --git a/whatmaps/debiandistro.py b/whatmaps/debiandistro.py index 3a47d50..af95bc2 100644 --- a/whatmaps/debiandistro.py +++ b/whatmaps/debiandistro.py @@ -29,6 +29,7 @@ import logging import os import subprocess import sys +import string from . distro import Distro from . debianpkg import DebianPkg diff --git a/whatmaps/redhatdistro.py b/whatmaps/redhatdistro.py index 4d9f5cf..9300648 100644 --- a/whatmaps/redhatdistro.py +++ b/whatmaps/redhatdistro.py @@ -20,7 +20,6 @@ import re import subprocess from . distro import Distro -from . pkg import PkgError from . rpmpkg import RpmPkg class RedHatDistro(Distro): -- cgit v1.2.3 From c56870bfd90ed2d6730c7d74dee01c2ed4a85d34 Mon Sep 17 00:00:00 2001 From: Guido Günther Date: Thu, 26 Jun 2014 09:40:35 +0200 Subject: Fix informal message Packages don't map shared objects --- whatmaps/command.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/whatmaps/command.py b/whatmaps/command.py index e02b176..29996b1 100755 --- a/whatmaps/command.py +++ b/whatmaps/command.py @@ -209,7 +209,7 @@ def main(argv): if level > logging.INFO: logging.error("Getting Service listing not implemented " "for distribution %s - rerun with --verbose to see a list" - "of binaries and packages to map a shared objects from %s", + "of binaries that map a shared objects from %s", distro.id, args) return 1 else: -- cgit v1.2.3 From fe1c3af968020b906a8ca417fee1dd80673d9b9f Mon Sep 17 00:00:00 2001 From: Guido Günther Date: Mon, 21 Apr 2014 21:18:52 +0200 Subject: Move detect_distro to Distro --- tests/test_distro.py | 12 ++++++++++-- whatmaps/command.py | 43 ++--------------------------------------- whatmaps/debiandistro.py | 4 ++-- whatmaps/distro.py | 50 ++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 64 insertions(+), 45 deletions(-) diff --git a/tests/test_distro.py b/tests/test_distro.py index e22da68..c67b0f6 100644 --- a/tests/test_distro.py +++ b/tests/test_distro.py @@ -16,9 +16,9 @@ import unittest -from whatmaps.distro import Distro +from mock import patch -from . import context +from whatmaps.distro import Distro, detect class Pkg(object): name = 'doesnotmatter' @@ -38,3 +38,11 @@ class TestDistro(unittest.TestCase): self.assertEqual(Distro.pkg_services(Pkg), []) self.assertEqual(Distro.pkg_service_blacklist(Pkg), []) self.assertFalse(Distro.has_apt()) + + def test_detect_via_lsb_release_module(self): + "Detect distro via lsb_release" + with patch('lsb_release.get_distro_information', return_value={'ID': 'Debian'}): + # Make sure we don't use the fallback + with patch('os.path.exists', return_value=False): + d = detect() + self.assertEqual(d.id, 'Debian') diff --git a/whatmaps/command.py b/whatmaps/command.py index 29996b1..b942a9a 100755 --- a/whatmaps/command.py +++ b/whatmaps/command.py @@ -22,20 +22,13 @@ import errno import glob import os import logging -import subprocess import sys from optparse import OptionParser -try: - import lsb_release -except ImportError: - lsb_release = None from . process import Process -from . debiandistro import DebianDistro -from . redhatdistro import FedoraDistro +from . distro import Distro from . pkg import PkgError - def check_maps(procs, shared_objects): restart_procs = {} for proc in procs: @@ -60,38 +53,6 @@ def get_all_pids(): return processes -def detect_distro(): - id = None - - if lsb_release: - id = lsb_release.get_distro_information()['ID'] - else: - try: - lsb_cmd = subprocess.Popen(['lsb_release', '--id', '-s'], - stdout=subprocess.PIPE, - stderr=subprocess.PIPE) - output = lsb_cmd.communicate()[0] - if not lsb_cmd.returncode: - id = output.strip() - except OSError: - # id is None in this case - pass - - if id == DebianDistro.id: - return DebianDistro - elif id == FedoraDistro.id: - return FedoraDistro - else: - if os.path.exists('/usr/bin/dpkg'): - logging.warning("Unknown distro but dpkg found, assuming Debian") - return DebianDistro - elif os.path.exists('/bin/rpm'): - logging.warning("Unknown distro but rpm found, assuming Fedora") - return FedoraDistro - else: - return None - - def write_cmd_file(services, cmd_file, distro): "Write out commands needed to restart the services to a file" out = open(cmd_file, 'w') @@ -130,7 +91,7 @@ def main(argv): logging.basicConfig(level=level, format='%(levelname)s: %(message)s') - distro = detect_distro() + distro = Distro.detect() if not distro: logging.error("Unsupported Distribution") return 1 diff --git a/whatmaps/debiandistro.py b/whatmaps/debiandistro.py index af95bc2..d608d8f 100644 --- a/whatmaps/debiandistro.py +++ b/whatmaps/debiandistro.py @@ -31,11 +31,11 @@ import subprocess import sys import string -from . distro import Distro +import distro from . debianpkg import DebianPkg from . pkg import PkgError -class DebianDistro(Distro): +class DebianDistro(distro.Distro): "Debian (dpkg) based distribution" id = 'Debian' diff --git a/whatmaps/distro.py b/whatmaps/distro.py index 5625955..b2e2c82 100644 --- a/whatmaps/distro.py +++ b/whatmaps/distro.py @@ -15,8 +15,16 @@ # along with this program. If not, see . # +import logging +import os import subprocess + +try: + import lsb_release +except ImportError: + lsb_release = None + class Distro(object): """ A distribution @@ -74,3 +82,45 @@ class Distro(object): def has_apt(klass): """Does the distribution use apt""" return False + + @staticmethod + def detect(): + return detect() + +import debiandistro +import redhatdistro + +def detect(): + """ + Detect the distribution we run on. Returns C{None} if the + distribution is unknown. + """ + id = None + + if lsb_release: + id = lsb_release.get_distro_information()['ID'] + else: + try: + lsb_cmd = subprocess.Popen(['lsb_release', '--id', '-s'], + stdout=subprocess.PIPE, + stderr=subprocess.PIPE) + output = lsb_cmd.communicate()[0] + if not lsb_cmd.returncode: + id = output.strip() + except OSError: + # id is None in this case + pass + + if id == debiandistro.DebianDistro.id: + return debiandistro.DebianDistro + elif id == redhatdistro.FedoraDistro.id: + return redhatdistro.FedoraDistro + else: + if os.path.exists('/usr/bin/dpkg'): + logging.warning("Unknown distro but dpkg found, assuming Debian") + return debiandistro.DebianDistro + elif os.path.exists('/bin/rpm'): + logging.warning("Unknown distro but rpm found, assuming Fedora") + return debiandistro.FedoraDistro + else: + return None -- cgit v1.2.3 From 8771fbcf584d1d5f6eaa8aad9dc9978e94176dfc Mon Sep 17 00:00:00 2001 From: Guido Günther Date: Tue, 1 Jul 2014 11:12:37 +0200 Subject: Document class variables --- whatmaps/distro.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/whatmaps/distro.py b/whatmaps/distro.py index b2e2c82..a575a70 100644 --- a/whatmaps/distro.py +++ b/whatmaps/distro.py @@ -28,7 +28,15 @@ except ImportError: class Distro(object): """ A distribution + @cvar id: distro id as returned by lsb-release + + @cvar service_blacklist: services that should never be restarted + @cvar _pkg_services: A C{dict} that maps packages to services. In + case we find binaries that match a key in this hash restart + the services listed in values. + @cvar _pkg_service_blacklist: if we find binaries in the package + listed as key don't restart services listed in values """ id = None service_blacklist = set() -- cgit v1.2.3 From c5f9fedeb25646b32134e0f82b2ea64854d3718d Mon Sep 17 00:00:00 2001 From: Guido Günther Date: Fri, 11 Jul 2014 18:47:12 +0200 Subject: Drop unused variable --- tests/test_debiandistro.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_debiandistro.py b/tests/test_debiandistro.py index c01efd8..b2041ff 100644 --- a/tests/test_debiandistro.py +++ b/tests/test_debiandistro.py @@ -94,7 +94,7 @@ class TestDebianDistro(unittest.TestCase): pkgs = {'pkg1': DebianPkg('pkg1'), 'pkg2': DebianPkg('pkg2'), } - with patch('apt_pkg.Cache') as mock: + with patch('apt_pkg.Cache'): DebianDistro.filter_security_updates(pkgs) apt_pkg_init.assert_called_once_with() apt_pkg_acquire.assert_called_once_with() -- cgit v1.2.3 From 3ff8c7d8227119474543b0fd4dbee0817676472e Mon Sep 17 00:00:00 2001 From: Guido Günther Date: Fri, 11 Jul 2014 17:37:59 +0200 Subject: Move find_services and find_pkgs out of main() --- whatmaps/command.py | 74 ++++++++++++++++++++++++++++++++++------------------- 1 file changed, 48 insertions(+), 26 deletions(-) diff --git a/whatmaps/command.py b/whatmaps/command.py index b942a9a..3c22e20 100755 --- a/whatmaps/command.py +++ b/whatmaps/command.py @@ -64,6 +64,48 @@ def write_cmd_file(services, cmd_file, distro): os.chmod(cmd_file, 0o755) +def find_pkgs(procs, distro): + """ + Find packages that contain the binaries of the given processes + """ + pkgs = {} + for proc in procs: + pkg = distro.pkg_by_file(proc) + if not pkg: + logging.warning("No package found for '%s' - restart manually" % proc) + else: + if pkg.name in pkgs: + pkgs[pkg.name].procs.append(proc) + else: + pkg.procs = [ proc ] + pkgs[pkg.name] = pkg + + logging.info("Packages that ship the affected binaries:") + for pkg in pkgs.values(): + logging.info(" Pkg: %s, binaries: %s" % (pkg.name, pkg.procs)) + + return pkgs + + +def find_services(pkgs, distro): + """ + Determine the services in pkgs honoring distro specific mappings + and blacklists + """ + all_services = set() + + for pkg in pkgs.values(): + services = set(pkg.services + distro.pkg_services(pkg)) + services -= set(distro.pkg_service_blacklist(pkg)) + if not services: + logging.warning("No service script found in '%s' for '%s' " + "- restart manually" % (pkg.name, pkg.procs)) + else: + all_services.update(services) + all_services -= distro.service_blacklist + return all_services + + def main(argv): shared_objects = [] @@ -138,34 +180,14 @@ def main(argv): for exe, pids in restart_procs.items(): logging.debug(" Exe: %s Pids: %s", exe, pids), - # Find packages that contain the binaries of these processes - pkgs = {} - for proc in restart_procs: - pkg = distro.pkg_by_file(proc) - if not pkg: - logging.warning("No package found for '%s' - restart manually" % proc) - else: - if pkg.name in pkgs: - pkgs[pkg.name].procs.append(proc) - else: - pkg.procs = [ proc ] - pkgs[pkg.name] = pkg - - logging.info("Packages that ship the affected binaries:") - for pkg in pkgs.values(): - logging.info(" Pkg: %s, binaries: %s" % (pkg.name, pkg.procs)) + # Find the packages that contain the binaries the processes are + # executing + pkgs = find_pkgs(restart_procs, distro) - all_services = set() + # Find the services in these packages honoring distro specific + # mappings and blacklists try: - for pkg in pkgs.values(): - services = set(pkg.services + distro.pkg_services(pkg)) - services -= set(distro.pkg_service_blacklist(pkg)) - if not services: - logging.warning("No service script found in '%s' for '%s' " - "- restart manually" % (pkg.name, pkg.procs)) - else: - all_services.update(services) - all_services -= distro.service_blacklist + all_services = find_services(pkgs, distro) except NotImplementedError: if level > logging.INFO: logging.error("Getting Service listing not implemented " -- cgit v1.2.3 From f758314abe0c3c4cc2b06ca5a24c7288a0af41ed Mon Sep 17 00:00:00 2001 From: Guido Günther Date: Fri, 11 Jul 2014 17:23:10 +0200 Subject: Add systemd support --- tests/test_systemd.py | 62 ++++++++++++++++++++++++++++++++++++++++++++++ whatmaps/command.py | 64 ++++++++++++++++++++++++++++++++---------------- whatmaps/debiandistro.py | 7 +++++- whatmaps/systemd.py | 41 +++++++++++++++++++++++++++++++ 4 files changed, 152 insertions(+), 22 deletions(-) create mode 100644 tests/test_systemd.py create mode 100644 whatmaps/systemd.py diff --git a/tests/test_systemd.py b/tests/test_systemd.py new file mode 100644 index 0000000..2fbdfdc --- /dev/null +++ b/tests/test_systemd.py @@ -0,0 +1,62 @@ +# vim: set fileencoding=utf-8 : +# (C) 2014 Guido Günther +# 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 3 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, see . +"""Test L{whatmaps.process} config""" + +import unittest + +from mock import patch + +from whatmaps.systemd import Systemd +from whatmaps.process import Process + +class Process(object): + def __init__(self, pid): + self.pid = pid + +class TestSystemd(unittest.TestCase): + def test_is_init(self): + """Check if we create a systemd object if systemd is the init system in use""" + with patch('os.path.exists', return_value=True): + self.assertIsNotNone(Systemd()) + + def test_is_not_init(self): + """Check if we raise an exception if systemd isn't tthe init system in use""" + with patch('os.path.exists', return_value=False): + self.assertRaises(ValueError, Systemd) + + def test_process_to_unit(self): + p = Process(952) + output = """libvirt-bin.service - Virtualization daemon + Loaded: loaded (/lib/systemd/system/libvirt-bin.service; enabled) + Active: active (running) since Fr 2014-07-11 16:10:55 CEST; 50min ago + Docs: man:libvirtd(8) + http://libvirt.org + Main PID: 952 (libvirtd) + CGroup: name=systemd:/system/libvirt-bin.service + ├─ 952 /usr/sbin/libvirtd + └─1355 /usr/sbin/dnsmasq --conf-file=/var/lib/libvirt/dnsmasq/default.conf + """ + with patch('os.path.exists', return_value=True): + with patch('subprocess.Popen') as mock: + PopenMock = mock.return_value + PopenMock.communicate.return_value = [output] + PopenMock.returncode = 0 + result = Systemd().process_to_unit(p) + self.assertEqual(result, 'libvirt-bin.service') + + PopenMock.returncode = 1 + result = Systemd().process_to_unit(p) + self.assertIsNone(result) + diff --git a/whatmaps/command.py b/whatmaps/command.py index 3c22e20..7690ef8 100755 --- a/whatmaps/command.py +++ b/whatmaps/command.py @@ -28,6 +28,7 @@ from optparse import OptionParser from . process import Process from . distro import Distro from . pkg import PkgError +from . systemd import Systemd def check_maps(procs, shared_objects): restart_procs = {} @@ -106,8 +107,25 @@ def find_services(pkgs, distro): return all_services +def find_systemd_units(procmap, distro): + """Find systemd units that contain the given processes""" + units = set() + + for dummy, procs in procmap.items(): + for proc in procs: + unit = Systemd.process_to_unit(proc) + if not unit: + logging.warning("No systemd unit found for '%s'" + "- restart manually" % proc.exe) + else: + units.add(unit) + units -= set([ service + '.service' for service in distro.service_blacklist ]) + return units + + def main(argv): shared_objects = [] + services = None parser = OptionParser(usage='%prog [options] pkg1 [pkg2 pkg3 pkg4]') parser.add_option("--debug", action="store_true", dest="debug", @@ -180,34 +198,38 @@ def main(argv): for exe, pids in restart_procs.items(): logging.debug(" Exe: %s Pids: %s", exe, pids), - # Find the packages that contain the binaries the processes are - # executing - pkgs = find_pkgs(restart_procs, distro) + if Systemd.is_running(): + logging.debug("Detected Systemd") + services = find_systemd_units(restart_procs, distro) + else: + # Find the packages that contain the binaries the processes are + # executing + pkgs = find_pkgs(restart_procs, distro) - # Find the services in these packages honoring distro specific - # mappings and blacklists - try: - all_services = find_services(pkgs, distro) - except NotImplementedError: - if level > logging.INFO: - logging.error("Getting Service listing not implemented " - "for distribution %s - rerun with --verbose to see a list" - "of binaries that map a shared objects from %s", - distro.id, args) - return 1 - else: - return 0 + # Find the services in these packages honoring distro specific + # mappings and blacklists + try: + services = find_services(pkgs, distro) + except NotImplementedError: + if level > logging.INFO: + logging.error("Getting Service listing not implemented " + "for distribution %s - rerun with --verbose to see a list" + "of binaries that map a shared objects from %s", + distro.id, args) + return 1 + else: + return 0 if options.restart: - if options.print_cmds and all_services: - write_cmd_file(all_services, options.print_cmds, distro) + if options.print_cmds and services: + write_cmd_file(services, options.print_cmds, distro) else: - for service in all_services: + for service in services: logging.info("Restarting %s" % service) distro.restart_service(service) - elif all_services: + elif services: print("Services that possibly need to be restarted:") - for s in all_services: + for s in services: print(s) return 0 diff --git a/whatmaps/debiandistro.py b/whatmaps/debiandistro.py index d608d8f..5333a35 100644 --- a/whatmaps/debiandistro.py +++ b/whatmaps/debiandistro.py @@ -34,6 +34,7 @@ import string import distro from . debianpkg import DebianPkg from . pkg import PkgError +from . systemd import Systemd class DebianDistro(distro.Distro): "Debian (dpkg) based distribution" @@ -73,8 +74,12 @@ class DebianDistro(distro.Distro): return DebianPkg(pkg) @classmethod - def restart_service_cmd(klass, name): + def restart_service_cmd(klass, service): """The command that should be used to start a service""" + if Systemd.is_running() and service.endswith('.service'): + name = service[:-len('.service')] + else: + name = service return ['invoke-rc.d', name, 'restart'] @classmethod diff --git a/whatmaps/systemd.py b/whatmaps/systemd.py new file mode 100644 index 0000000..add6d0e --- /dev/null +++ b/whatmaps/systemd.py @@ -0,0 +1,41 @@ +# vim: set fileencoding=utf-8 : +# +# (C) 2014 Guido Günther +# 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 3 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, see . +# + +import os +import subprocess + + +class Systemd(object): + """Systemd init system""" + + def __init__(self): + if not self.is_running(): + raise ValueError("Systemd not running") + + @staticmethod + def is_running(): + return os.path.exists("/run/systemd/system") + + @staticmethod + def process_to_unit(process): + cmd = ['systemctl', 'status', "%d" % process.pid] + systemctl_status = subprocess.Popen(cmd, stdout=subprocess.PIPE) + output = systemctl_status.communicate()[0] + if systemctl_status.returncode: + return None + else: + return output.split()[0] -- cgit v1.2.3 From 836bffc3f25d5752f8c72ba2c547318aea62faae Mon Sep 17 00:00:00 2001 From: Guido Günther Date: Fri, 11 Jul 2014 19:55:00 +0200 Subject: Make imports python2 and python3 compatible Do this again and I'll rewrite you in ruby. --- whatmaps/debiandistro.py | 4 ++-- whatmaps/distro.py | 16 ++++++++-------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/whatmaps/debiandistro.py b/whatmaps/debiandistro.py index 5333a35..9294c9f 100644 --- a/whatmaps/debiandistro.py +++ b/whatmaps/debiandistro.py @@ -31,12 +31,12 @@ import subprocess import sys import string -import distro +import whatmaps.distro from . debianpkg import DebianPkg from . pkg import PkgError from . systemd import Systemd -class DebianDistro(distro.Distro): +class DebianDistro(whatmaps.distro.Distro): "Debian (dpkg) based distribution" id = 'Debian' diff --git a/whatmaps/distro.py b/whatmaps/distro.py index a575a70..f0f08eb 100644 --- a/whatmaps/distro.py +++ b/whatmaps/distro.py @@ -95,8 +95,8 @@ class Distro(object): def detect(): return detect() -import debiandistro -import redhatdistro +import whatmaps.debiandistro +import whatmaps.redhatdistro def detect(): """ @@ -119,16 +119,16 @@ def detect(): # id is None in this case pass - if id == debiandistro.DebianDistro.id: - return debiandistro.DebianDistro - elif id == redhatdistro.FedoraDistro.id: - return redhatdistro.FedoraDistro + if id == whatmaps.debiandistro.DebianDistro.id: + return whatmaps.debiandistro.DebianDistro + elif id == whatmaps.redhatdistro.FedoraDistro.id: + return whatmaps.redhatdistro.FedoraDistro else: if os.path.exists('/usr/bin/dpkg'): logging.warning("Unknown distro but dpkg found, assuming Debian") - return debiandistro.DebianDistro + return whatmaps.debiandistro.DebianDistro elif os.path.exists('/bin/rpm'): logging.warning("Unknown distro but rpm found, assuming Fedora") - return debiandistro.FedoraDistro + return whatmaps.debiandistro.FedoraDistro else: return None -- cgit v1.2.3 From 5e9df7763328f998805b28aff874b56b67d1bd88 Mon Sep 17 00:00:00 2001 From: Guido Günther Date: Mon, 7 Jul 2014 14:19:43 +0200 Subject: Skip lsb_release tests when module is missing --- tests/test_debiandistro.py | 7 +++++++ tests/test_distro.py | 8 ++++++++ 2 files changed, 15 insertions(+) diff --git a/tests/test_debiandistro.py b/tests/test_debiandistro.py index b2041ff..617005c 100644 --- a/tests/test_debiandistro.py +++ b/tests/test_debiandistro.py @@ -23,6 +23,12 @@ try: except ImportError: have_apt_pkg=False +try: + import lsb_release + have_lsb_release=True +except ImportError: + have_lsb_release=False + from whatmaps.debiandistro import DebianDistro from whatmaps.debianpkg import DebianPkg @@ -90,6 +96,7 @@ class TestDebianDistro(unittest.TestCase): @patch('apt_pkg.init') @patch('apt_pkg.Acquire') @unittest.skipUnless(have_apt_pkg, "apt_pkg not installed") + @unittest.skipUnless(have_lsb_release, "lsb_release not installed") def test_filter_security_updates(self, apt_pkg_acquire, apt_pkg_init): pkgs = {'pkg1': DebianPkg('pkg1'), 'pkg2': DebianPkg('pkg2'), diff --git a/tests/test_distro.py b/tests/test_distro.py index c67b0f6..88fa984 100644 --- a/tests/test_distro.py +++ b/tests/test_distro.py @@ -18,6 +18,12 @@ import unittest from mock import patch +try: + import lsb_release + have_lsb_release=True +except ImportError: + have_lsb_release=False + from whatmaps.distro import Distro, detect class Pkg(object): @@ -39,6 +45,8 @@ class TestDistro(unittest.TestCase): self.assertEqual(Distro.pkg_service_blacklist(Pkg), []) self.assertFalse(Distro.has_apt()) + + @unittest.skipUnless(have_lsb_release, "lsb_release not installed") def test_detect_via_lsb_release_module(self): "Detect distro via lsb_release" with patch('lsb_release.get_distro_information', return_value={'ID': 'Debian'}): -- cgit v1.2.3