/mandos/trunk

To get this branch, use:
bzr branch http://bzr.recompile.se/loggerhead/mandos/trunk

« back to all changes in this revision

Viewing changes to mandos-ctl

  • Committer: Teddy Hogeborn
  • Date: 2019-07-30 17:03:57 UTC
  • Revision ID: teddy@recompile.se-20190730170357-jte0piul5mq7j5pr
Server: Reap zombies created by multiprocessing.Process()

When creating checkers as multiprocessing.Process() objects, the
multiprocessing module also creates a parent process (for the
call_pipe() function) to call the actual checker process, but this
parent process is not reaped.  This is not a huge problem, since the
zombie is always reaped automatically the next time the multiprocess
starts a new process, but the zombies can be up to as many as there
have ever been simultaneous checker processes.  To fix this, the
process object must be join():ed when they report completion of the
child checker process.

* mandos (Client): Fix doc string to correctly state that
                   Client.checker is a multiprocess.Process() and not
                   a subprocess.Popen() object.
  (Client.checker_callback): After the returncode of the checker
                             process has been read, wait for the
                             self.checker Process object to finish by
                             calling join() on it.

Reported-by: Peter Palfrader <weasel@debian.org>

Show diffs side-by-side

added added

removed removed

Lines of Context:
46
46
import tempfile
47
47
import contextlib
48
48
 
49
 
if sys.version_info.major == 2:
50
 
    __metaclass__ = type
51
 
 
52
49
try:
53
50
    import pydbus
54
51
    import gi
56
53
except ImportError:
57
54
    import dbus as dbus_python
58
55
    pydbus = None
59
 
    class gi:
 
56
    class gi(object):
60
57
        """Dummy gi module, for the tests"""
61
 
        class repository:
62
 
            class GLib:
 
58
        class repository(object):
 
59
            class GLib(object):
63
60
                class Error(Exception):
64
61
                    pass
65
62
 
81
78
 
82
79
locale.setlocale(locale.LC_ALL, "")
83
80
 
84
 
version = "1.8.8"
 
81
version = "1.8.4"
85
82
 
86
83
 
87
84
def main():
470
467
        parser.error("--remove can only be combined with --deny")
471
468
 
472
469
 
473
 
class dbus:
 
470
class dbus(object):
474
471
 
475
 
    class SystemBus:
 
472
    class SystemBus(object):
476
473
 
477
474
        object_manager_iface = "org.freedesktop.DBus.ObjectManager"
478
475
        def get_managed_objects(self, busname, objectpath):
524
521
        pass
525
522
 
526
523
 
527
 
class dbus_python_adapter:
 
524
class dbus_python_adapter(object):
528
525
 
529
526
    class SystemBus(dbus.MandosBus):
530
527
        """Use dbus-python"""
584
581
                                     self.client_interface, key,
585
582
                                     value)
586
583
 
587
 
    class SilenceLogger:
 
584
    class SilenceLogger(object):
588
585
        "Simple context manager to silence a particular logger"
589
586
        def __init__(self, loggername):
590
587
            self.logger = logging.getLogger(loggername)
619
616
                return new_object
620
617
 
621
618
 
622
 
class pydbus_adapter:
 
619
class pydbus_adapter(object):
623
620
    class SystemBus(dbus.MandosBus):
624
621
        def __init__(self, module=pydbus):
625
622
            self.pydbus = module
715
712
    return commands
716
713
 
717
714
 
718
 
class command:
 
715
class command(object):
719
716
    """A namespace for command classes"""
720
717
 
721
 
    class Base:
 
718
    class Base(object):
722
719
        """Abstract base class for commands"""
723
720
        def run(self, clients, bus=None):
724
721
            """Normal commands should implement run_on_one_client(),
787
784
                keywords = self.all_keywords
788
785
            print(self.TableOfClients(clients.values(), keywords))
789
786
 
790
 
        class TableOfClients:
 
787
        class TableOfClients(object):
791
788
            tableheaders = {
792
789
                "Name": "Name",
793
790
                "Enabled": "Enabled",
1024
1021
                                                     "output"))
1025
1022
 
1026
1023
 
1027
 
class Unique:
 
1024
class Unique(object):
1028
1025
    """Class for objects which exist only to be unique objects, since
1029
1026
unittest.mock.sentinel only exists in Python 3.3"""
1030
1027
 
1314
1311
class Test_dbus_python_adapter_SystemBus(TestCaseWithAssertLogs):
1315
1312
 
1316
1313
    def MockDBusPython_func(self, func):
1317
 
        class mock_dbus_python:
 
1314
        class mock_dbus_python(object):
1318
1315
            """mock dbus-python module"""
1319
 
            class exceptions:
 
1316
            class exceptions(object):
1320
1317
                """Pseudo-namespace"""
1321
1318
                class DBusException(Exception):
1322
1319
                    pass
1323
 
            class SystemBus:
 
1320
            class SystemBus(object):
1324
1321
                @staticmethod
1325
1322
                def get_object(busname, objectpath):
1326
1323
                    DBusObject = collections.namedtuple(
1340
1337
                                    dbus_interface=dbus_interface)
1341
1338
                    return DBusObject(methodname=method,
1342
1339
                                      Set=set_property)
1343
 
            class Boolean:
 
1340
            class Boolean(object):
1344
1341
                def __init__(self, value):
1345
1342
                    self.value = bool(value)
1346
1343
                def __bool__(self):
1558
1555
            self.call_method(bus, "methodname", "busname",
1559
1556
                             "objectpath", "interface")
1560
1557
 
1561
 
    class fake_dbus_python_raises_exception_on_connect:
 
1558
    class fake_dbus_python_raises_exception_on_connect(object):
1562
1559
        """fake dbus-python module"""
1563
 
        class exceptions:
 
1560
        class exceptions(object):
1564
1561
            """Pseudo-namespace"""
1565
1562
            class DBusException(Exception):
1566
1563
                pass
1574
1571
 
1575
1572
 
1576
1573
class Test_dbus_python_adapter_CachingBus(unittest.TestCase):
1577
 
    class mock_dbus_python:
 
1574
    class mock_dbus_python(object):
1578
1575
        """mock dbus-python modules"""
1579
 
        class SystemBus:
 
1576
        class SystemBus(object):
1580
1577
            @staticmethod
1581
1578
            def get_object(busname, objectpath):
1582
1579
                return Unique()
1628
1625
class Test_pydbus_adapter_SystemBus(TestCaseWithAssertLogs):
1629
1626
 
1630
1627
    def Stub_pydbus_func(self, func):
1631
 
        class stub_pydbus:
 
1628
        class stub_pydbus(object):
1632
1629
            """stub pydbus module"""
1633
 
            class SystemBus:
 
1630
            class SystemBus(object):
1634
1631
                @staticmethod
1635
1632
                def get(busname, objectpath):
1636
1633
                    DBusObject = collections.namedtuple(
1682
1679
            self.call_method(bus, "methodname", "busname",
1683
1680
                             "objectpath", "interface")
1684
1681
 
1685
 
    class fake_pydbus_raises_exception_on_connect:
 
1682
    class fake_pydbus_raises_exception_on_connect(object):
1686
1683
        """fake dbus-python module"""
1687
1684
        @classmethod
1688
1685
        def SystemBus(cls):
1692
1689
            return Bus(get=get)
1693
1690
 
1694
1691
    def test_set_property_uses_setattr(self):
1695
 
        class Object:
 
1692
        class Object(object):
1696
1693
            pass
1697
1694
        obj = Object()
1698
 
        class pydbus_spy:
1699
 
            class SystemBus:
 
1695
        class pydbus_spy(object):
 
1696
            class SystemBus(object):
1700
1697
                @staticmethod
1701
1698
                def get(busname, objectpath):
1702
1699
                    return {"interface": obj}
1709
1706
    def test_get_suppresses_xml_deprecation_warning(self):
1710
1707
        if sys.version_info.major >= 3:
1711
1708
            return
1712
 
        class stub_pydbus_get:
1713
 
            class SystemBus:
 
1709
        class stub_pydbus_get(object):
 
1710
            class SystemBus(object):
1714
1711
                @staticmethod
1715
1712
                def get(busname, objectpath):
1716
1713
                    warnings.warn_explicit(
1724
1721
 
1725
1722
 
1726
1723
class Test_pydbus_adapter_CachingBus(unittest.TestCase):
1727
 
    class stub_pydbus:
 
1724
    class stub_pydbus(object):
1728
1725
        """stub pydbus module"""
1729
 
        class SystemBus:
 
1726
        class SystemBus(object):
1730
1727
            @staticmethod
1731
1728
            def get(busname, objectpath):
1732
1729
                return Unique()