summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGuido Günther <agx@sigxcpu.org>2016-09-23 13:15:27 +0200
committerGuido Günther <agx@sigxcpu.org>2016-09-23 13:15:27 +0200
commit9ffc5cbb599ea3859804979f1570d17a5c0373a2 (patch)
tree8118b317885ac543c1399497bdf9643c8b887340
parentead569ed946d5e7414ec4c328d4d8b2a6bb3009c (diff)
parent48651cda01095017ddc5e67a2491c02a44027ab5 (diff)
Merge tag 'v0.0.12' into debian/master
whatmaps v0.0.12
-rw-r--r--.travis.yml7
-rw-r--r--requirements.txt5
-rw-r--r--setup.cfg4
-rw-r--r--setup.py32
-rw-r--r--tests/context.py6
-rw-r--r--tests/test_debiandistro.py15
-rw-r--r--tests/test_debianpkg.py2
-rw-r--r--tests/test_distro.py27
-rw-r--r--tests/test_pkg.py3
-rw-r--r--tests/test_process.py6
-rw-r--r--tests/test_redhatdistro.py1
-rw-r--r--tests/test_rpmpkg.py1
-rw-r--r--tests/test_systemd.py23
-rw-r--r--tox.ini2
-rwxr-xr-xwhatmaps/command.py42
-rw-r--r--whatmaps/debiandistro.py59
-rw-r--r--whatmaps/debianpkg.py6
-rw-r--r--whatmaps/distro.py32
-rw-r--r--whatmaps/pkg.py5
-rw-r--r--whatmaps/process.py1
-rw-r--r--whatmaps/redhatdistro.py8
-rw-r--r--whatmaps/rpmpkg.py5
-rw-r--r--whatmaps/systemd.py3
23 files changed, 205 insertions, 90 deletions
diff --git a/.travis.yml b/.travis.yml
new file mode 100644
index 0000000..838cd99
--- /dev/null
+++ b/.travis.yml
@@ -0,0 +1,7 @@
+---
+language: python
+python:
+ - "3.4"
+ - "3.5"
+install: "pip install -r requirements.txt"
+script: flake8
diff --git a/requirements.txt b/requirements.txt
new file mode 100644
index 0000000..4da1296
--- /dev/null
+++ b/requirements.txt
@@ -0,0 +1,5 @@
+coverage>=2.85
+flake8>=3
+mock
+nose>=0.11.1
+nosexcover>=1.0.7
diff --git a/setup.cfg b/setup.cfg
index ee9ac0e..aca3f68 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -1,2 +1,6 @@
[nosetests]
cover-package=whatmaps
+
+[flake8]
+# E501: ignore line length
+ignore=E501
diff --git a/setup.py b/setup.py
index be05caa..6cdf17b 100644
--- a/setup.py
+++ b/setup.py
@@ -15,30 +15,32 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
+import os
from setuptools import setup
data_files = []
try:
import lsb_release
- if (lsb_release.get_distro_information()['ID'] in [ 'Debian' ] or
- os.path.exists('/etc/debian_version')):
- data_files = [('../etc/apt/apt.conf.d/',
- ['apt/50whatmaps_apt']),
- ('../etc/apt/apt.conf.d/',
- ['apt/20services']),
- ]
+ if (lsb_release.get_distro_information()['ID'] in ['Debian'] or
+ os.path.exists('/etc/debian_version')):
+ data_files = [('../etc/apt/apt.conf.d/',
+ ['apt/50whatmaps_apt']),
+ ('../etc/apt/apt.conf.d/',
+ ['apt/20services']),
+ ]
except ImportError:
pass
-setup(name = "whatmaps",
- author = 'Guido Günther',
- author_email = 'agx@sigxcpu.org',
- data_files = data_files,
- packages = ['whatmaps'],
- entry_points = {
- 'console_scripts': [ 'whatmaps = whatmaps.command:run' ],
+
+setup(name="whatmaps",
+ author='Guido Günther',
+ author_email='agx@sigxcpu.org',
+ data_files=data_files,
+ packages=['whatmaps'],
+ entry_points={
+ 'console_scripts': ['whatmaps = whatmaps.command:run'],
},
-)
+ )
# vim:et:ts=4:sw=4:et:sts=4:ai:set list listchars=tab\:»·,trail\:·:
diff --git a/tests/context.py b/tests/context.py
index 5878771..8900a30 100644
--- a/tests/context.py
+++ b/tests/context.py
@@ -29,19 +29,22 @@ projectdir = os.path.dirname(os.path.dirname(os.path.abspath(whatmaps.__file__))
_chdir_backup = None
_tmpdirs = []
+
def chdir(dir):
global _chdir_backup
if not _chdir_backup:
_chdir_backup = os.path.abspath(os.curdir)
os.chdir(str(dir))
+
def new_tmpdir(name):
global _tmpdirs
- prefix='whatmaps_%s_' % name
+ prefix = 'whatmaps_%s_' % name
tmpdir = TmpDir(prefix)
_tmpdirs.append(tmpdir)
return tmpdir
+
def teardown():
if _chdir_backup:
os.chdir(_chdir_backup)
@@ -49,6 +52,7 @@ def teardown():
tmpdir.rmdir()
del _tmpdirs[:]
+
class TmpDir(object):
def __init__(self, suffix='', prefix='tmp'):
diff --git a/tests/test_debiandistro.py b/tests/test_debiandistro.py
index 617005c..b976d65 100644
--- a/tests/test_debiandistro.py
+++ b/tests/test_debiandistro.py
@@ -18,20 +18,21 @@ import unittest
from mock import patch
try:
- import apt_pkg
- have_apt_pkg=True
+ import apt_pkg # noqa: F401
+ have_apt_pkg = True
except ImportError:
- have_apt_pkg=False
+ have_apt_pkg = False
try:
- import lsb_release
- have_lsb_release=True
+ import lsb_release # noqa: F401
+ have_lsb_release = True
except ImportError:
- have_lsb_release=False
+ have_lsb_release = False
from whatmaps.debiandistro import DebianDistro
from whatmaps.debianpkg import DebianPkg
+
class TestDebianDistro(unittest.TestCase):
def test_vars(self):
"""Check Debian distro vars"""
@@ -100,7 +101,7 @@ class TestDebianDistro(unittest.TestCase):
def test_filter_security_updates(self, apt_pkg_acquire, apt_pkg_init):
pkgs = {'pkg1': DebianPkg('pkg1'),
'pkg2': DebianPkg('pkg2'),
- }
+ }
with patch('apt_pkg.Cache'):
DebianDistro.filter_security_updates(pkgs)
apt_pkg_init.assert_called_once_with()
diff --git a/tests/test_debianpkg.py b/tests/test_debianpkg.py
index 72ce8fb..6c130ed 100644
--- a/tests/test_debianpkg.py
+++ b/tests/test_debianpkg.py
@@ -20,10 +20,10 @@ from mock import patch
from whatmaps.debianpkg import DebianPkg
+
class TestDebianPkg(unittest.TestCase):
def test_services(self):
with patch('whatmaps.pkg.Pkg._get_contents') as mock:
mock.return_value = ['/etc/init.d/aservice', '/usr/bin/afile']
p = DebianPkg('doesnotmatter')
self.assertEqual(p.services, ['aservice'])
-
diff --git a/tests/test_distro.py b/tests/test_distro.py
index 409c1c6..21df2c0 100644
--- a/tests/test_distro.py
+++ b/tests/test_distro.py
@@ -19,16 +19,17 @@ import unittest
from mock import patch
try:
- import lsb_release
- have_lsb_release=True
+ import lsb_release # noqa: F401
+ have_lsb_release = True
except ImportError:
- have_lsb_release=False
-
+ have_lsb_release = False
from whatmaps.distro import Distro, detect
+
class Pkg(object):
name = 'doesnotmatter'
+
class TestDistro(unittest.TestCase):
def test_abstract(self):
"""Check abstract method signatures"""
@@ -45,7 +46,6 @@ 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"
@@ -54,3 +54,20 @@ class TestDistro(unittest.TestCase):
with patch('os.path.exists', return_value=False):
d = detect()
self.assertEqual(d.id, 'Debian')
+
+ def test_filter_services_empty(self):
+ d = Distro()
+ self.assertEqual(set(['foo', 'bar']),
+ d.filter_services(['foo', 'bar']))
+
+ def test_filter_services_one(self):
+ d = Distro()
+ d.service_blacklist_re = ['^f..']
+ self.assertEqual(set(['bar']),
+ d.filter_services(['foo', 'bar']))
+
+ def test_filter_services_all(self):
+ d = Distro()
+ d.service_blacklist_re = ['^f..', '^b..']
+ self.assertEqual(set(),
+ d.filter_services(['foo', 'bar']))
diff --git a/tests/test_pkg.py b/tests/test_pkg.py
index b7707b8..2f2ef56 100644
--- a/tests/test_pkg.py
+++ b/tests/test_pkg.py
@@ -15,12 +15,13 @@
"""Test L{whatmaps.process} config"""
import unittest
-from mock import patch
+from mock import patch
from whatmaps.pkg import Pkg, PkgError
from . import context
+
class TestPkg(unittest.TestCase):
def setUp(self):
self.tmpdir = context.new_tmpdir(__name__)
diff --git a/tests/test_process.py b/tests/test_process.py
index 91f5431..e9cc1e0 100644
--- a/tests/test_process.py
+++ b/tests/test_process.py
@@ -15,7 +15,6 @@
"""Test L{whatmaps.process} config"""
import os
-import sys
import unittest
import random
@@ -23,6 +22,7 @@ from whatmaps.process import Process
from . import context
+
class TestWhatmapsProcess(unittest.TestCase):
def setUp(self):
self.tmpdir = context.new_tmpdir(__name__)
@@ -33,7 +33,7 @@ class TestWhatmapsProcess(unittest.TestCase):
self.exe = os.path.join(self.piddir, 'exe')
self.cmdline = os.path.join(self.piddir, 'cmdline')
self.maps = os.path.join(self.piddir, 'maps')
- self._write_cmdline('doesnotmatter') # Write at least an empty cmdline
+ self._write_cmdline('doesnotmatter') # Write at least an empty cmdline
self._write_exe_symlink('acommand')
self._write_maps([['f32b43221000-7f32b4522000',
'---p',
@@ -47,7 +47,7 @@ class TestWhatmapsProcess(unittest.TestCase):
'fe:02',
'1704011',
'/lib/x86_64-linux-gnu/libselinux.so.1'],
- ])
+ ])
def _write_exe_symlink(self, name):
exe = os.path.join(str(self.tmpdir), name)
diff --git a/tests/test_redhatdistro.py b/tests/test_redhatdistro.py
index 438adf8..ab39426 100644
--- a/tests/test_redhatdistro.py
+++ b/tests/test_redhatdistro.py
@@ -20,6 +20,7 @@ from mock import patch
from whatmaps.redhatdistro import RedHatDistro
from whatmaps.rpmpkg import RpmPkg
+
class TestRedHatDistro(unittest.TestCase):
def test_vars(self):
"""Check RedHat distro vars"""
diff --git a/tests/test_rpmpkg.py b/tests/test_rpmpkg.py
index 064f059..0eb2175 100644
--- a/tests/test_rpmpkg.py
+++ b/tests/test_rpmpkg.py
@@ -20,6 +20,7 @@ from mock import patch
from whatmaps.rpmpkg import RpmPkg
+
class TestRpmPkg(unittest.TestCase):
def test_services(self):
with patch('whatmaps.pkg.Pkg._get_contents') as mock:
diff --git a/tests/test_systemd.py b/tests/test_systemd.py
index f5af3c9..7615497 100644
--- a/tests/test_systemd.py
+++ b/tests/test_systemd.py
@@ -19,12 +19,13 @@ 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"""
@@ -60,3 +61,23 @@ class TestSystemd(unittest.TestCase):
result = Systemd().process_to_unit(p)
self.assertIsNone(result)
+ def test_process_user_session(self):
+ p = Process(952)
+ output = """● session-8762.scope - Session 8762 of user root
+ Loaded: loaded
+ Drop-In: /run/systemd/system/session-8762.scope.d
+ └─50-After-systemd-logind\x2eservice.conf, 50-After-systemd-user-sessions\x2eservice.conf, 50-Description.conf, 50-SendSIGHUP.conf, 50-Slice.conf
+ Active: active (running) since Thu 2016-04-07 20:53:52 CEST; 19min ago
+ CGroup: /user.slice/user-0.slice/session-8762.scope
+ ├─21150 sshd: root@pts/0
+ ├─21155 -bash
+ ├─23956 /usr/bin/python /usr/bin/whatmaps --debug libc6
+ └─23962 systemctl status 21155
+ """.encode('utf-8')
+ 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
+ with self.assertRaisesRegexp(ValueError, "Can't parse service name from session-8762.scope - Session 8762 of user root"):
+ Systemd().process_to_unit(p)
diff --git a/tox.ini b/tox.ini
index 68a25f8..346069a 100644
--- a/tox.ini
+++ b/tox.ini
@@ -4,7 +4,7 @@
# and then run "tox" from this directory.
[tox]
-envlist = py27, py33, py34
+envlist = py34, py35
[testenv]
commands = python setup.py nosetests
diff --git a/whatmaps/command.py b/whatmaps/command.py
index 0f8e433..e28a8b9 100755
--- a/whatmaps/command.py
+++ b/whatmaps/command.py
@@ -17,7 +17,6 @@
#
-
import errno
import glob
import os
@@ -30,15 +29,16 @@ from . distro import Distro
from . pkg import PkgError
from . systemd import Systemd
+
def check_maps(procs, shared_objects):
restart_procs = {}
for proc in procs:
for so in shared_objects:
if proc.maps(so):
if proc.exe in restart_procs:
- restart_procs[proc.exe] += [ proc ]
+ restart_procs[proc.exe] += [proc]
else:
- restart_procs[proc.exe] = [ proc ]
+ restart_procs[proc.exe] = [proc]
break
return restart_procs
@@ -78,7 +78,7 @@ def find_pkgs(procs, distro):
if pkg.name in pkgs:
pkgs[pkg.name].procs.append(proc)
else:
- pkg.procs = [ proc ]
+ pkg.procs = [proc]
pkgs[pkg.name] = pkg
if pkgs:
@@ -117,21 +117,32 @@ def find_systemd_units(procmap, distro):
try:
unit = Systemd.process_to_unit(proc)
except ValueError as e:
- logging.warning("No systemd unit found for '%s': %s"
+ logging.warning("No systemd unit found for '%s': %s "
"- restart manually" % (proc.exe, e))
continue
if not unit:
- logging.warning("No systemd unit found for '%s'"
+ 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 ])
+ units -= set([service + '.service' for service in distro.service_blacklist])
return units
+def filter_services(distro, services):
+ filtered = distro.filter_services(services)
+ diff = services - filtered
+ if len(diff):
+ logging.warning("Filtered out blacklisted service%s %s - restart manually",
+ 's' if len(diff) > 1 else '',
+ ', '.join(diff))
+ return filtered
+
+
def main(argv):
shared_objects = []
services = None
+ ret = 0
parser = OptionParser(usage='%prog [options] pkg1 [pkg2 pkg3 pkg4]')
parser.add_option("--debug", action="store_true", dest="debug",
@@ -157,7 +168,7 @@ def main(argv):
logging.basicConfig(level=level,
format='%(levelname)s: %(message)s')
- distro = Distro.detect()
+ distro = Distro.detect()()
if not distro:
logging.error("Unsupported Distribution")
return 1
@@ -165,7 +176,7 @@ def main(argv):
logging.debug("Detected distribution: '%s'", distro.id)
if args:
- pkgs = [ distro.pkg(arg) for arg in args ]
+ pkgs = [distro.pkg(arg) for arg in args]
elif options.apt and distro.has_apt():
try:
pkgs = distro.read_apt_pipeline()
@@ -174,7 +185,9 @@ def main(argv):
return 1
if not pkgs:
return 0
- pkgs = distro.filter_security_updates(pkgs)
+ pkgs, notfound = distro.filter_security_updates(pkgs)
+ if notfound:
+ logging.warning("Pkgs %s not found in apt cache" % ", ".join(notfound))
logging.debug("Security Upgrades: %s" % pkgs)
else:
parser.print_help()
@@ -185,8 +198,8 @@ def main(argv):
try:
shared_objects += pkg.shared_objects
except PkgError:
- logging.error("Cannot parse contents of %s" % pkg.name)
- return 1
+ logging.error("Cannot parse contents of %s - skipping it" % pkg.name)
+ ret = 1
logging.debug("Found shared objects:")
for so in shared_objects:
logging.debug(" %s", so)
@@ -226,6 +239,8 @@ def main(argv):
else:
return 0
+ services = filter_services(distro, services)
+
if options.restart:
if options.print_cmds and services:
write_cmd_file(services, options.print_cmds, distro)
@@ -238,7 +253,8 @@ def main(argv):
for s in services:
print(s)
- return 0
+ return ret
+
def run():
return(main(sys.argv))
diff --git a/whatmaps/debiandistro.py b/whatmaps/debiandistro.py
index 32f3774..4fcce54 100644
--- a/whatmaps/debiandistro.py
+++ b/whatmaps/debiandistro.py
@@ -36,30 +36,37 @@ from . debianpkg import DebianPkg
from . pkg import PkgError
from . systemd import Systemd
+
class DebianDistro(Distro):
"Debian (dpkg) based distribution"
id = 'Debian'
- _pkg_services = { 'apache2-mpm-worker': [ 'apache2' ],
- 'apache2-mpm-prefork': [ 'apache2' ],
- 'apache2.2-bin': [ 'apache2' ],
- 'apache2-bin': [ 'apache2' ],
- 'dovecot-imapd': [ 'dovecot' ],
- 'dovecot-pop3d': [ 'dovecot' ],
- 'exim4-daemon-light': [ 'exim4' ],
- 'exim4-daemon-heavy': [ 'exim4' ],
- 'libvirt-daemon': [ 'libvirtd' ],
- 'openjdk-6-jre-headless': ['jenkins', 'tomcat7'],
- 'openjdk-7-jre-headless': ['jenkins', 'tomcat7'],
- 'qemu-system-x86_64': [ 'libvirt-guests' ],
- }
+ _pkg_services = {
+ 'apache2-mpm-worker': ['apache2'],
+ 'apache2-mpm-prefork': ['apache2'],
+ 'apache2.2-bin': ['apache2'],
+ 'apache2-bin': ['apache2'],
+ 'dovecot-imapd': ['dovecot'],
+ 'dovecot-pop3d': ['dovecot'],
+ 'exim4-daemon-light': ['exim4'],
+ 'exim4-daemon-heavy': ['exim4'],
+ 'libvirt-daemon': ['libvirtd'],
+ 'openjdk-6-jre-headless': ['jenkins', 'tomcat7'],
+ 'openjdk-7-jre-headless': ['jenkins', 'tomcat7'],
+ 'qemu-system-x86_64': ['libvirt-guests'],
+ }
# Per package blacklist
- _pkg_service_blacklist = { 'libvirt-bin': [ 'libvirt-guests' ] }
+ _pkg_service_blacklist = {'libvirt-bin': ['libvirt-guests']}
# Per distro blacklist
service_blacklist = set(['kvm', 'qemu-kvm', 'qemu-system-x86'])
+ # Per distro regex filter
+ service_blacklist_re = set([
+ '^user@[0-9]+.service$', # Restarting systemd user service aborts the session
+ ])
+
@classmethod
def pkg(klass, name):
return DebianPkg(name)
@@ -67,8 +74,8 @@ class DebianDistro(Distro):
@classmethod
def pkg_by_file(klass, path):
find_file = subprocess.Popen(['dpkg-query', '-S', path],
- stdout=subprocess.PIPE,
- stderr=subprocess.PIPE)
+ stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE)
output = find_file.communicate()[0]
if find_file.returncode:
return None
@@ -124,12 +131,11 @@ class DebianDistro(Distro):
(pkgname, oldversion, compare, newversion, filename) = line.split()
if filename == '**CONFIGURE**':
- if oldversion != '-': # Updates only
+ if oldversion != '-': # Updates only
pkgs[pkgname] = DebianPkg(pkgname)
pkgs[pkgname].version = newversion
return pkgs
-
@classmethod
def _security_update_origins(klass):
"Determine security update origins from apt configuration"
@@ -138,9 +144,10 @@ class DebianDistro(Distro):
raise PkgError("lsb_release not found, can't determine security updates")
codename = lsb_release.get_distro_information()['CODENAME']
+
def _subst(line):
- mapping = {'distro_codename' : codename,
- 'distro_id' : klass.id, }
+ mapping = {'distro_codename': codename,
+ 'distro_id': klass.id, }
return string.Template(line).substitute(mapping)
origins = []
@@ -151,7 +158,6 @@ class DebianDistro(Distro):
logging.debug("Security Update Origins: %s", origins)
return origins
-
@classmethod
def filter_security_updates(klass, pkgs):
"""Filter on security updates"""
@@ -160,14 +166,19 @@ class DebianDistro(Distro):
raise PkgError("apt_pkg not installed, can't determine security updates")
apt_pkg.init()
- acquire = apt_pkg.Acquire()
+ apt_pkg.Acquire()
cache = apt_pkg.Cache()
security_update_origins = klass._security_update_origins()
security_updates = {}
+ notfound = []
for pkg in list(pkgs.values()):
- cache_pkg = cache[pkg.name]
+ try:
+ cache_pkg = cache[pkg.name]
+ except KeyError:
+ notfound.append(pkg)
+ continue
for cache_version in cache_pkg.version_list:
if pkg.version == cache_version.ver_str:
for pfile, _ in cache_version.file_list:
@@ -176,4 +187,4 @@ class DebianDistro(Distro):
pfile.archive == origin[1]:
security_updates[pkg] = pkg
break
- return security_updates
+ return (security_updates, notfound)
diff --git a/whatmaps/debianpkg.py b/whatmaps/debianpkg.py
index 8a3349d..0192513 100644
--- a/whatmaps/debianpkg.py
+++ b/whatmaps/debianpkg.py
@@ -19,17 +19,18 @@ import re
from . pkg import Pkg
+
class DebianPkg(Pkg):
type = 'Debian'
_init_script_re = re.compile('/etc/init.d/[\w\-\.]')
- _list_contents = ['dpkg-query', '-L', '${pkg_name}' ]
+ _list_contents = ['dpkg-query', '-L', '${pkg_name}']
def __init__(self, name):
Pkg.__init__(self, name)
@property
def services(self):
- if self._services != None:
+ if self._services is not None:
return self._services
self._services = []
@@ -39,4 +40,3 @@ class DebianPkg(Pkg):
if self._init_script_re.match(line):
self._services.append(os.path.basename(line.strip()))
return self._services
-
diff --git a/whatmaps/distro.py b/whatmaps/distro.py
index f0f08eb..29d2dc2 100644
--- a/whatmaps/distro.py
+++ b/whatmaps/distro.py
@@ -17,6 +17,7 @@
import logging
import os
+import re
import subprocess
@@ -25,6 +26,7 @@ try:
except ImportError:
lsb_release = None
+
class Distro(object):
"""
A distribution
@@ -32,6 +34,8 @@ class Distro(object):
@cvar id: distro id as returned by lsb-release
@cvar service_blacklist: services that should never be restarted
+ @cvar service_blacklist_re: regex list of services that should
+ never be restartet
@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.
@@ -40,6 +44,8 @@ class Distro(object):
"""
id = None
service_blacklist = set()
+ service_blacklist_re = set()
+
_pkg_services = {}
_pkg_blacklist = {}
_pkg_service_blacklist = {}
@@ -75,8 +81,8 @@ class Distro(object):
List of services that package pkg needs restarted that aren't part
of pkg itself
"""
- return [ s for s in klass._pkg_services.get(pkg.name, [])
- if klass.is_service_installed(s) ]
+ return [s for s in klass._pkg_services.get(pkg.name, [])
+ if klass.is_service_installed(s)]
@classmethod
def pkg_service_blacklist(klass, pkg):
@@ -86,6 +92,17 @@ class Distro(object):
"""
return klass._pkg_service_blacklist.get(pkg.name, [])
+ def filter_services(self, services):
+ """
+ Filter out servies that match service_blacklist_re
+ """
+ ret = []
+ matchers = [re.compile(b) for b in self.service_blacklist_re]
+ for s in services:
+ if not any([m.match(s) for m in matchers]):
+ ret.append(s)
+ return set(ret)
+
@classmethod
def has_apt(klass):
"""Does the distribution use apt"""
@@ -95,8 +112,9 @@ class Distro(object):
def detect():
return detect()
-import whatmaps.debiandistro
-import whatmaps.redhatdistro
+import whatmaps.debiandistro # noqa: E402
+import whatmaps.redhatdistro # noqa: E402
+
def detect():
"""
@@ -110,11 +128,11 @@ def detect():
else:
try:
lsb_cmd = subprocess.Popen(['lsb_release', '--id', '-s'],
- stdout=subprocess.PIPE,
- stderr=subprocess.PIPE)
+ stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE)
output = lsb_cmd.communicate()[0]
if not lsb_cmd.returncode:
- id = output.strip()
+ id = output.strip()
except OSError:
# id is None in this case
pass
diff --git a/whatmaps/pkg.py b/whatmaps/pkg.py
index 4290d0b..7aafd5a 100644
--- a/whatmaps/pkg.py
+++ b/whatmaps/pkg.py
@@ -19,6 +19,7 @@ import re
import string
import subprocess
+
class PkgError(Exception):
pass
@@ -55,8 +56,8 @@ class Pkg(object):
if self._contents:
return self._contents
else:
- cmd = [ string.Template(arg).substitute(arg, pkg_name=self.name)
- for arg in self._list_contents ]
+ cmd = [string.Template(arg).substitute(arg, pkg_name=self.name)
+ for arg in self._list_contents]
list_contents = subprocess.Popen(cmd,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
diff --git a/whatmaps/process.py b/whatmaps/process.py
index a39da89..78165a7 100644
--- a/whatmaps/process.py
+++ b/whatmaps/process.py
@@ -20,6 +20,7 @@ import logging
import os
import re
+
class Process(object):
"""A process - Linux only so far, needs /proc mounted"""
deleted_re = re.compile(r"(?P<exe>.*) \(deleted\)$")
diff --git a/whatmaps/redhatdistro.py b/whatmaps/redhatdistro.py
index 0427c30..4b17f3c 100644
--- a/whatmaps/redhatdistro.py
+++ b/whatmaps/redhatdistro.py
@@ -21,10 +21,11 @@ import subprocess
from . distro import Distro
from . rpmpkg import RpmPkg
+
class RedHatDistro(Distro):
"RPM based distribution"""
_pkg_re = re.compile(r'(?P<pkg>[\w\-\+]+)-(?P<ver>[\w\.]+)'
- '-(?P<rel>[\w\.]+)\.(?P<arch>.+)')
+ '-(?P<rel>[\w\.]+)\.(?P<arch>.+)')
@classmethod
def pkg(klass, name):
@@ -33,8 +34,8 @@ class RedHatDistro(Distro):
@classmethod
def pkg_by_file(klass, path):
find_file = subprocess.Popen(['rpm', '-qf', path],
- stdout=subprocess.PIPE,
- stderr=subprocess.PIPE)
+ stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE)
output = find_file.communicate()[0]
if find_file.returncode:
return None
@@ -52,4 +53,3 @@ class RedHatDistro(Distro):
class FedoraDistro(RedHatDistro):
id = 'Fedora'
-
diff --git a/whatmaps/rpmpkg.py b/whatmaps/rpmpkg.py
index 595edd2..493dd5a 100644
--- a/whatmaps/rpmpkg.py
+++ b/whatmaps/rpmpkg.py
@@ -19,17 +19,18 @@ import re
from . pkg import Pkg
+
class RpmPkg(Pkg):
type = 'RPM'
_init_script_re = re.compile('/etc/rc.d/init.d/[\w\-\.]')
- _list_contents = [ 'rpm', '-ql', '$pkg_name' ]
+ _list_contents = ['rpm', '-ql', '$pkg_name']
def __init__(self, name):
Pkg.__init__(self, name)
@property
def services(self):
- if self._services != None:
+ if self._services is not None:
return self._services
self._services = []
diff --git a/whatmaps/systemd.py b/whatmaps/systemd.py
index 9bc03b1..d4f45fe 100644
--- a/whatmaps/systemd.py
+++ b/whatmaps/systemd.py
@@ -43,5 +43,8 @@ class Systemd(object):
return parts[0]
elif parts[1].endswith('.service'):
return parts[1]
+ elif parts[1].startswith('session-') and parts[1].endswith('.scope'):
+ msg = output.decode('utf-8').split('\n')[0][2:]
+ raise ValueError("Can't parse service name from %s" % msg)
else:
raise ValueError("Can't parse service name from: (%s %s)" % (parts[0], parts[1]))