Example #1
0
 def __init__(self):
     super(RegionEventLoop, self).__init__()
     self.services = MultiService()
     self.handle = None
Example #2
0
 def setUp(self):
     super(TestProvisioningServiceMaker, self).setUp()
     self.useFixture(ClusterConfigurationFixture())
     self.patch(provisioningserver, "services", MultiService())
     self.patch_autospec(crochet, "no_setup")
     self.patch_autospec(logger, "configure")
Example #3
0
def eliot_logging_service(log_file, reactor, capture_stdout):
    service = MultiService()
    ThreadedFileWriter(log_file, reactor).setServiceParent(service)
    EliotObserver(capture_stdout=capture_stdout).setServiceParent(service)
    return service
Example #4
0
# Copyright 2012-2016 Canonical Ltd.  This software is licensed under the
# GNU Affero General Public License version 3 (see the file LICENSE).
"""The MAAS Provisioning Server, now referred to as Cluster."""

from twisted.application.service import MultiService

# The cluster's services. This is initialised by
# ProvisioningServiceMaker.
services = MultiService()
Example #5
0
def _main_async(reactor, argv=None, _abort_for_test=False):
    if argv is None:
        argv = sys.argv

    if not _abort_for_test:
        # Some log messages would be discarded if we did not set up things early.
        configure_logging()

    # Option parsing is done before importing the main modules so as to avoid the cost of initializing gnuradio if we are aborting early. TODO: Make that happen for createConfig too.
    argParser = argparse.ArgumentParser(prog=argv[0])
    argParser.add_argument('config_path',
                           metavar='CONFIG',
                           help='path of configuration directory or file')
    argParser.add_argument(
        '--create',
        dest='createConfig',
        action='store_true',
        help='write template configuration file to CONFIG and exit')
    argParser.add_argument('-g, --go',
                           dest='openBrowser',
                           action='store_true',
                           help='open the UI in a web browser')
    argParser.add_argument(
        '--force-run',
        dest='force_run',
        action='store_true',
        help='Run DSP even if no client is connected (for debugging).')
    args = argParser.parse_args(args=argv[1:])

    # Verify we can actually run.
    # Note that this must be done before we actually load core modules, because we might get an import error then.
    version_report = yield _check_versions()
    if version_report:
        print(version_report, file=sys.stderr)
        sys.exit(1)

    # Write config file and exit if asked ...
    if args.createConfig:
        write_default_config(args.config_path)
        _log.info('Created default configuration at: {config_path}',
                  config_path=args.config_path)
        sys.exit(0)  # TODO: Consider using a return value or something instead

    # ... else read config file
    config_obj = Config(reactor=reactor, log=_log)
    try:
        execute_config(config_obj, args.config_path)
        yield config_obj._wait_and_validate()
    except ConfigException:
        print_config_exception(sys.exc_info(), sys.stderr)
        defer.returnValue(None)
        return

    _log.info('Constructing...')
    app = config_obj._create_app()

    reactor.addSystemEventTrigger('during', 'shutdown', app.close_all_devices)

    _log.info('Restoring state...')
    pfg = PersistenceFileGlue(reactor=reactor,
                              root_object=app,
                              filename=config_obj._state_filename,
                              get_defaults=_app_defaults)

    _log.info('Starting web server...')
    services = MultiService()
    for maker in config_obj._service_makers:
        IService(maker(app)).setServiceParent(services)
    services.startService()

    _log.info('ShinySDR is ready.')

    for service in services:
        # TODO: should have an interface (currently no proper module to put it in)
        service.announce(args.openBrowser)

    if args.force_run:
        _log.debug('force_run')
        # TODO kludge, make this less digging into guts
        app.get_receive_flowgraph().get_monitor().state()['fft'].subscribe2(
            lambda v: None, the_subscription_context)

    if _abort_for_test:
        services.stopService()
        yield pfg.sync()
        defer.returnValue(app)
    else:
        yield defer.Deferred()  # never fires
Example #6
0
def getService(address):
    service = MultiService()
    return service
Example #7
0
def _main_async(reactor, argv=None, _abort_for_test=False):
    if argv is None:
        argv = sys.argv

    if not _abort_for_test:
        # Configure logging. Some log messages would be discarded if we did not set up things early
        # TODO: Consult best practices for Python and Twisted logging.
        # TODO: Logs which are observably relevant should be sent to the client (e.g. the warning of refusing to have more receivers active)
        logging.basicConfig(level=logging.INFO)
        log.startLoggingWithObserver(
            log.PythonLoggingObserver(loggerName='shinysdr').emit, False)

    # Option parsing is done before importing the main modules so as to avoid the cost of initializing gnuradio if we are aborting early. TODO: Make that happen for createConfig too.
    argParser = argparse.ArgumentParser(prog=argv[0])
    argParser.add_argument('config_path',
                           metavar='CONFIG',
                           help='path of configuration directory or file')
    argParser.add_argument(
        '--create',
        dest='createConfig',
        action='store_true',
        help='write template configuration file to CONFIG and exit')
    argParser.add_argument('-g, --go',
                           dest='openBrowser',
                           action='store_true',
                           help='open the UI in a web browser')
    argParser.add_argument(
        '--force-run',
        dest='force_run',
        action='store_true',
        help='Run DSP even if no client is connected (for debugging).')
    args = argParser.parse_args(args=argv[1:])

    # Verify we can actually run.
    # Note that this must be done before we actually load core modules, because we might get an import error then.
    version_report = yield _check_versions()
    if version_report:
        print >> sys.stderr, version_report
        sys.exit(1)

    # We don't actually use shinysdr.devices directly, but we want it to be guaranteed available in the context of the config file.
    # pylint: disable=unused-variable
    import shinysdr.devices as lazy_devices
    import shinysdr.source as lazy_source  # legacy shim

    # Load config file
    if args.createConfig:
        write_default_config(args.config_path)
        log.msg('Created default configuration at: ' + args.config_path)
        sys.exit(0)  # TODO: Consider using a return value or something instead
    else:
        configObj = Config(reactor)
        execute_config(configObj, args.config_path)
        yield configObj._wait_and_validate()

        stateFile = configObj._state_filename

    def noteDirty():
        if stateFile is not None:
            # just immediately write (revisit this when more performance is needed)
            with open(stateFile, 'w') as f:
                json.dump(app.state_to_json(), f)

    def restore(root, get_defaults):
        if stateFile is not None:
            if os.path.isfile(stateFile):
                root.state_from_json(json.load(open(stateFile, 'r')))
                # make a backup in case this code version misreads the state and loses things on save (but only if the load succeeded, in case the file but not its backup is bad)
                shutil.copyfile(stateFile, stateFile + '~')
            else:
                root.state_from_json(get_defaults(root))

    log.msg('Constructing...')
    app = configObj._create_app()

    singleton_reactor.addSystemEventTrigger('during', 'shutdown',
                                            app.close_all_devices)

    log.msg('Restoring state...')
    restore(app, _app_defaults)

    log.msg('Starting web server...')
    services = MultiService()
    for maker in configObj._service_makers:
        IService(maker(app, noteDirty)).setServiceParent(services)
    services.startService()

    log.msg('ShinySDR is ready.')

    for service in services:
        # TODO: should have an interface (currently no proper module to put it in)
        service.announce(args.openBrowser)

    if args.force_run:
        log.msg('force_run')
        from gnuradio.gr import msg_queue
        # TODO kludge, make this less digging into guts
        app.get_receive_flowgraph().monitor.get_fft_distributor().subscribe(
            msg_queue(limit=2))

    if _abort_for_test:
        services.stopService()
        defer.returnValue((app, noteDirty))
    else:
        yield defer.Deferred()  # never fires
Example #8
0
File: aqd.py Project: ned21/aquilon
class AQDMaker(object):
    implements(IServiceMaker, IPlugin)
    tapname = "aqd"
    description = "Aquilon Daemon"
    options = Options

    def makeService(self, options):
        # Start up coverage ASAP.
        coverage_dir = options["coveragedir"]
        if coverage_dir:
            os.makedirs(coverage_dir, 0755)
            if options["coveragerc"]:
                coveragerc = options["coveragerc"]
            else:
                coveragerc = None
            self.coverage = coverage.coverage(config_file=coveragerc)
            self.coverage.erase()
            self.coverage.start()

        # Get the config object.
        config = Config(configfile=options["config"])

        # Helper for finishing off the coverage report.
        def stop_coverage():
            log.msg("Finishing coverage")
            self.coverage.stop()
            aquilon_srcdir = os.path.join(config.get("broker", "srcdir"),
                                          "lib", "python2.6", "aquilon")
            sourcefiles = []
            for dirpath, dirnames, filenames in os.walk(aquilon_srcdir):
                # FIXME: try to do this from the coverage config file
                if dirpath.endswith("aquilon"):
                    dirnames.remove("client")
                elif dirpath.endswith("aqdb"):
                    dirnames.remove("utils")

                for filename in filenames:
                    if not filename.endswith('.py'):
                        continue
                    sourcefiles.append(os.path.join(dirpath, filename))

            self.coverage.html_report(sourcefiles, directory=coverage_dir)
            self.coverage.xml_report(sourcefiles,
                                     outfile=os.path.join(
                                         coverage_dir, "aqd.xml"))

            with open(os.path.join(coverage_dir, "aqd.coverage"),
                      "w") as outfile:
                self.coverage.report(sourcefiles, file=outfile)

        # Make sure the coverage report gets generated.
        if coverage_dir:
            reactor.addSystemEventTrigger('after', 'shutdown', stop_coverage)

        # Set up the environment...
        m = Modulecmd()
        log_module_load(m, config.get("broker", "CheckNet_module"))
        if config.has_option("database", "module"):
            log_module_load(m, config.get("database", "module"))
        sys.path.append(config.get("protocols", "directory"))

        # Set this up before the aqdb libs get imported...
        integrate_logging(config)

        progname = os.path.split(sys.argv[0])[1]
        if progname == 'aqd':
            if config.get('broker', 'mode') != 'readwrite':
                log.msg("Broker started with aqd symlink, "
                        "setting config mode to readwrite")
                config.set('broker', 'mode', 'readwrite')
        if progname == 'aqd_readonly':
            if config.get('broker', 'mode') != 'readonly':
                log.msg("Broker started with aqd_readonly symlink, "
                        "setting config mode to readonly")
                config.set('broker', 'mode', 'readonly')
        log.msg("Loading broker in mode %s" % config.get('broker', 'mode'))

        # Dynamic import means that we can parse config options before
        # importing aqdb.  This is a hack until aqdb can be imported without
        # firing up database connections.
        resources = __import__("aquilon.worker.resources", globals(), locals(),
                               ["RestServer"], -1)
        RestServer = getattr(resources, "RestServer")

        restServer = RestServer(config)
        openSite = AnonSite(restServer)

        # twisted is nicely changing the umask for us when the process is
        # set to daemonize.  This sets it back.
        restServer.set_umask()
        reactor.addSystemEventTrigger('after', 'startup', restServer.set_umask)
        reactor.addSystemEventTrigger('after', 'startup',
                                      restServer.set_thread_pool_size)

        sockdir = config.get("broker", "sockdir")
        if not os.path.exists(sockdir):
            os.makedirs(sockdir, 0700)
        os.chmod(sockdir, 0700)

        if options["usesock"]:
            return strports.service("unix:%s/aqdsock" % sockdir, openSite)

        openport = config.get("broker", "openport")
        if config.has_option("broker", "bind_address"):
            bind_address = config.get("broker", "bind_address").strip()
            openaddr = "tcp:%s:interface=%s" % (openport, bind_address)
        else:  # pragma: no cover
            bind_address = None
            openaddr = "tcp:%s" % openport

        # Return before firing up knc.
        if options["noauth"]:
            return strports.service(openaddr, openSite)

        sockname = os.path.join(sockdir, "kncsock")
        # This flag controls whether or not this process will start up
        # and monitor knc.  Except for noauth mode knc has to be running,
        # but this process doesn't have to be the thing that starts it up.
        if config.getboolean("broker", "run_knc") or \
           config.getboolean("broker", "run_git_daemon"):
            mon = GracefulProcessMonitor()
            # FIXME: Should probably run krb5_keytab here as well.
            # and/or verify that the keytab file exists.
            if config.getboolean("broker", "run_knc"):
                keytab = config.get("broker", "keytab")
                knc_args = [
                    "/usr/bin/env",
                    "KRB5_KTNAME=FILE:%s" % keytab,
                    config.get("kerberos", "knc"), "-lS", sockname
                ]
                if bind_address:
                    knc_args.append("-a")
                    knc_args.append(bind_address)
                knc_args.append(config.get("broker", "kncport"))
                mon.addProcess("knc", knc_args)
            if config.getboolean("broker", "run_git_daemon"):
                # The git daemon *must* be invoked using the form 'git-daemon'
                # instead of invoking git with a 'daemon' argument.  The latter
                # will fork and exec git-daemon, resulting in a new pid that
                # the process monitor won't know about!
                gitpath = config.get("broker", "git_path")
                gitdaemon = config.get("broker", "git_daemon")
                ospath = os.environ.get("PATH", "")
                args = [
                    "/usr/bin/env",
                    "PATH=%s:%s" % (gitpath, ospath), gitdaemon,
                    "--export-all",
                    "--base-path=%s" %
                    config.get("broker", "git_daemon_basedir")
                ]
                if config.has_option("broker", "git_port"):
                    args.append("--port=%s" % config.get("broker", "git_port"))
                if bind_address:
                    args.append("--listen=%s" % bind_address)
                args.append(config.get("broker", "kingdir"))
                mon.addProcess("git-daemon", args)
            mon.startService()
            reactor.addSystemEventTrigger('before', 'shutdown',
                                          mon.stopService)

        # This socket is created by twisted and only accessed by knc as
        # connections come in.
        if os.path.exists(sockname):
            try:
                log.msg("Attempting to remove old socket '%s'" % sockname)
                os.remove(sockname)
                log.msg("Succeeded removing old socket.")
            except OSError, e:
                log.msg("Could not remove old socket '%s': %s" % (sockname, e))

        unixsocket = "unix:%s" % sockname
        kncSite = KNCSite(restServer)

        multiService = MultiService()
        multiService.addService(strports.service(unixsocket, kncSite))
        if not options["authonly"]:
            multiService.addService(strports.service(openaddr, openSite))
        return multiService