This file is indexed.

/usr/lib/python2.7/dist-packages/landscape/service.py is in landscape-common 14.01-0ubuntu3.

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
import logging
import signal

from twisted.application.service import Application, Service
from twisted.application.app import startApplication

from landscape.log import rotate_logs
from landscape.reactor import LandscapeReactor
from landscape.deployment import get_versioned_persist, init_logging


class LandscapeService(Service, object):
    """Utility superclass for defining Landscape services.

    This sets up the reactor and L{Persist} object.

    @cvar service_name: The lower-case name of the service. This is used to
        generate the bpickle and the Unix socket filenames.
    @ivar config: A L{Configuration} object.
    @ivar reactor: A L{LandscapeReactor} object.
    @ivar persist: A L{Persist} object, if C{persist_filename} is defined.
    @ivar factory: A L{LandscapeComponentProtocolFactory}, it must be provided
        by instances of sub-classes.
    """
    reactor_factory = LandscapeReactor
    persist_filename = None

    def __init__(self, config):
        self.config = config
        try:
            from landscape.lib import bpickle_dbus
        except ImportError:
            pass
        else:
            bpickle_dbus.install()
        self.reactor = self.reactor_factory()
        if self.persist_filename:
            self.persist = get_versioned_persist(self)
        if not (self.config is not None and self.config.ignore_sigusr1):
            from twisted.internet import reactor
            signal.signal(
                signal.SIGUSR1,
                lambda signal, frame: reactor.callFromThread(rotate_logs))

    def startService(self):
        Service.startService(self)
        logging.info("%s started with config %s" % (
            self.service_name.capitalize(), self.config.get_config_filename()))

    def stopService(self):
        # We don't need to call port.stopListening(), because the reactor
        # shutdown sequence will do that for us.
        Service.stopService(self)
        logging.info("%s stopped with config %s" % (
            self.service_name.capitalize(), self.config.get_config_filename()))


def run_landscape_service(configuration_class, service_class, args):
    """Run a Landscape service.

    This function instantiates the specified L{LandscapeService} subclass and
    attaches the resulting service object to a Twisted C{Application}.  After
    that it starts the Twisted L{Application} and calls the
    L{LandscapeReactor.run} method of the L{LandscapeService}'s reactor.

    @param configuration_class: The service-specific subclass of
        L{Configuration} used to parse C{args} and build the C{service_class}
        object.
    @param service_class: The L{LandscapeService} subclass to create and start.
    @param args: Command line arguments used to initialize the configuration.
    """
    # Let's consider adding this:
    # from twisted.python.log import (
    #     startLoggingWithObserver, PythonLoggingObserver)
    # startLoggingWithObserver(PythonLoggingObserver().emit, setStdout=False)

    configuration = configuration_class()
    configuration.load(args)
    init_logging(configuration, service_class.service_name)
    application = Application("landscape-%s" % (service_class.service_name,))
    service = service_class(configuration)
    service.setServiceParent(application)

    if configuration.clones > 0:

        # Increase the timeout of AMP's MethodCalls
        # XXX: we should find a better way to expose this knot, and
        # not set it globally on the class
        from landscape.lib.amp import MethodCallSender
        MethodCallSender.timeout = 300

        # Create clones here because LandscapeReactor.__init__ would otherwise
        # cancel all scheduled delayed calls
        clones = []
        for i in range(configuration.clones):
            clone_config = configuration.clone()
            clone_config.computer_title += " Clone %d" % i
            clone_config.master_data_path = configuration.data_path
            clone_config.data_path += "-clone-%d" % i
            clone_config.log_dir += "-clone-%d" % i
            clone_config.is_clone = True
            clones.append(service_class(clone_config))

        configuration.is_clone = False

        def start_clones():
            # Spawn instances over the given time window
            start_clones_over = float(configuration.start_clones_over)
            delay = start_clones_over / configuration.clones

            for i, clone in enumerate(clones):

                def start(clone):
                    clone.setServiceParent(application)
                    clone.reactor.fire("run")

                service.reactor.call_later(delay * (i + 1), start, clone=clone)

        service.reactor.call_when_running(start_clones)

    startApplication(application, False)
    if configuration.ignore_sigint:
        signal.signal(signal.SIGINT, signal.SIG_IGN)

    service.reactor.run()