Пример #1
0
class WebBoxVHost:
    """ Class to manage and spawn Virtual Hosts, each with a different WebBox. """

    def __init__(self, config):
        self.config = config
       
        self.host = config['management']['host'] # hostname of the management interface
        self.port = config['management']['port'] # port to listen on
        self.srcdir = config['management']['srcdir'] # source directory of templates
        # TODO ssl port? or multiple ports?

        self.vhost = NameVirtualHost()

        # allow the config to be readable by .rpy files
        registry = Registry()
        registry.setComponent(WebBoxVHost, self)

        root = FileNoDirectoryListings(self.srcdir, registry=registry)
        # make .rpy python cgi
        root.processors = {'.rpy': script.ResourceScript}
        root.ignoreExt('.rpy')

        # hook in the vhost controller urls to /start /stop etc.
        root.putChild("start", WSGIResource(reactor, reactor.getThreadPool(), self.do_start))
        root.putChild("stop", WSGIResource(reactor, reactor.getThreadPool(), self.do_stop))

        class MgmtRealm(object):
            implements(IRealm)
            def requestAvatar(self, avatarId, mind, *interfaces):
                if IResource in interfaces:
                    return (IResource, root, lambda: None)
                logging.debug("Error in requestAvatar.")

        realm = MgmtRealm()
        portal = Portal(realm, [FilePasswordDB(config['htdigest'])]) #FIXME insecure passwords
        credentialFactory = DigestCredentialFactory("md5", "webbox") # webbox is the "realm" of the htdigest
        rootAuth = HTTPAuthSessionWrapper(portal, [credentialFactory])
        self.vhost.addHost(self.host, rootAuth)

        self.site = Site(self.vhost)
        reactor.listenTCP(self.port, self.site)
        # TODO ssl port?

        self.url = "http://"+self.host+":"+str(self.port)

        # load a web browser once the server has started
        def on_start(arg):
            logging.debug("Listening on: "+self.url)
            try:
                import webbrowser
                webbrowser.open(server_url)
            except Exception as e:
                pass # no web browser? no problem.
        def start_failed(arg):
            logging.debug("Startup failed: "+str(arg))

        # calls the web browser opening function above when the reactor has finished starting up
        d = Deferred()
        d.addCallbacks(on_start, start_failed)
        reactor.callWhenRunning(d.callback, "Server startup")

        logging.debug("Starting WebBox management interface on: "+self.url)

        # add vhosts already configured
        self.webboxes = {}
        self.add_vhosts()

        reactor.run()

    def start_vhost(self, vhost):
        """ Start the vhost with the definition 'vhost'. """
        vhost['status'] = "running"

        path = "webbox"

        webbox = WebBox(vhost['config'])
        resource = webbox.get_resource()

        self.vhost.addHost(vhost['host'], resource)
        self.webboxes[ vhost['host'] ] = webbox


    def stop_vhost(self, vhost):
        """ Stop the vhost with the defintion 'vhost'. """
        vhost['status'] = "stopped"
        self.vhost.removeHost(vhost['host'])
        webbox = self.webboxes[ vhost['host'] ]
        webbox.stop()


    def add_vhosts(self):
        """ Add the vhosts from the configuration. """
        for vhost in self.config['vhosts']:
            self.start_vhost(vhost)

    def get_config(self):
        for vhost in self.config['vhosts']:
            vhost['url_scheme'] = self.config['url_scheme']
            vhost['port'] = self.config['management']['port'] 
            if vhost['status'] == "stopped":
                vhost['modify'] = "Start"
                vhost['modify_action'] = "start"
            elif vhost['status'] == "running":
                vhost['modify'] = "Stop"
                vhost['modify_action'] = "stop"

        return self.config

    def do_start(self, environment, start_response):
        host = environment['PATH_INFO'][1:] # remove leading slash
        for vhost in self.config['vhosts']:
            if host == vhost['host']:
                self.start_vhost(vhost)
                start_response("302 Found", [("Content-type", "text/html"), ("Location", "/")] )
                return []

        start_response("404 Not Found", [("Content-type", "text/html")] )
        return ["That virtual host was not found."]

    def do_stop(self, environment, start_response):
        host = environment['PATH_INFO'][1:] # remove leading slash
        for vhost in self.config['vhosts']:
            if host == vhost['host']:
                self.stop_vhost(vhost)
                start_response("302 Found", [("Content-type", "text/html"), ("Location", "/")] )
                return []

        start_response("404 Not Found", [("Content-type", "text/html")] )
        return ["That virtual host was not found."]