This file is indexed.

/usr/lib/python3/dist-packages/maasserver/plugin.py is in python3-django-maas 2.4.0~beta2-6865-gec43e47e6-0ubuntu1.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
# Copyright 2014-2016 Canonical Ltd.  This software is licensed under the
# GNU Affero General Public License version 3 (see the file LICENSE).

"""Twisted Application Plugin code for the MAAS Region."""

__all__ = [
    "RegionAllInOneServiceMaker",
    "RegionMasterServiceMaker",
    "RegionWorkerServiceMaker",
]

import os
import signal
import time

from provisioningserver import logger
from provisioningserver.logger import LegacyLogger
from provisioningserver.utils.debug import (
    register_sigusr2_thread_dump_handler,
)
from twisted.application.service import IServiceMaker
from twisted.internet import reactor
from twisted.plugin import IPlugin
from twisted.python.threadable import isInIOThread
from zope.interface import implementer


log = LegacyLogger()


class Options(logger.VerbosityOptions):
    """Command-line options for `regiond`."""


@implementer(IServiceMaker, IPlugin)
class RegionWorkerServiceMaker:
    """Create the worker service for the Twisted plugin."""

    options = Options

    def __init__(self, name, description):
        self.tapname = name
        self.description = description

    def _set_pdeathsig(self):
        # Worker must die when the the master dies, no exceptions, no hanging
        # around so it must be killed.
        #
        # Sadly the only way to do this in python is to use ctypes. This tells
        # the kernel that when my parent dies to kill me.
        import ctypes
        libc = ctypes.CDLL("libc.so.6")
        libc.prctl(1, signal.SIGKILL)

    def _configureThreads(self):
        from maasserver.utils import threads
        threads.install_default_pool()
        threads.install_database_pool()

    def _configureLogging(self, verbosity: int):
        # Get something going with the logs.
        logger.configure(verbosity, logger.LoggingMode.TWISTD)

    def _configureDjango(self):
        # Some region services use the ORM at class-load time: force Django to
        # load the models first. This is OK to run in the reactor because
        # having Django -- most specifically the ORM -- up and running is a
        # prerequisite of almost everything in the region controller.
        import django
        django.setup()

    def _configureReactor(self):
        # Disable all database connections in the reactor.
        from maasserver.utils.orm import disable_all_database_connections
        if isInIOThread():
            disable_all_database_connections()
        else:
            reactor.callFromThread(disable_all_database_connections)

    def _configureCrochet(self):
        # Prevent other libraries from starting the reactor via crochet.
        # In other words, this makes crochet.setup() a no-op.
        import crochet
        crochet.no_setup()

    def makeService(self, options):
        """Construct the MAAS Region service."""
        register_sigusr2_thread_dump_handler()

        self._set_pdeathsig()
        self._configureThreads()
        self._configureLogging(options["verbosity"])
        self._configureDjango()
        self._configureReactor()
        self._configureCrochet()

        # Should the import services run in this worker.
        import_services = False
        if os.environ.get('MAAS_REGIOND_RUN_IMPORTER_SERVICE') == 'true':
            import_services = True

        # Populate the region's event-loop with services.
        from maasserver import eventloop
        eventloop.loop.populate(master=False, import_services=import_services)

        # Return the eventloop's services to twistd, which will then be
        # responsible for starting them all.
        return eventloop.loop.services


@implementer(IServiceMaker, IPlugin)
class RegionMasterServiceMaker(RegionWorkerServiceMaker):
    """Create the master service for the Twisted plugin."""

    options = Options

    def __init__(self, name, description):
        self.tapname = name
        self.description = description

    def _ensureConnection(self):
        # If connection is already made close it.
        from django.db import connection
        if connection.connection is not None:
            connection.close()

        # Loop forever until a connection can be made.
        while True:
            try:
                connection.ensure_connection()
            except Exception:
                log.err(_why=(
                    "Error starting: "
                    "Connection to database cannot be established."))
                time.sleep(1)
            else:
                # Connection made, now close it.
                connection.close()
                break

    def makeService(self, options):
        """Construct the MAAS Region service."""
        register_sigusr2_thread_dump_handler()

        self._configureThreads()
        self._configureLogging(options["verbosity"])
        self._configureDjango()
        self._configureReactor()
        self._configureCrochet()
        self._ensureConnection()

        # Populate the region's event-loop with services.
        from maasserver import eventloop
        eventloop.loop.populate(master=True)

        # Return the eventloop's services to twistd, which will then be
        # responsible for starting them all.
        return eventloop.loop.services


@implementer(IServiceMaker, IPlugin)
class RegionAllInOneServiceMaker(RegionMasterServiceMaker):
    """Create the all-in-one service for the Twisted plugin.

    This service runs all the Twisted services in the same process, instead
    of forking the workers.
    """

    options = Options

    def __init__(self, name, description):
        self.tapname = name
        self.description = description

    def makeService(self, options):
        """Construct the MAAS Region service."""
        register_sigusr2_thread_dump_handler()

        self._configureThreads()
        self._configureLogging(options["verbosity"])
        self._configureDjango()
        self._configureReactor()
        self._configureCrochet()
        self._ensureConnection()

        # Populate the region's event-loop with services.
        from maasserver import eventloop
        eventloop.loop.populate(
            master=True, all_in_one=True, import_services=True)

        # Return the eventloop's services to twistd, which will then be
        # responsible for starting them all.
        return eventloop.loop.services