loadSchema = True elif dbVersion.major < schema.VERSION.major: # schema too old loadSchema = True elif 'migrate' in argSet: # a migration was asked for loadSchema = True if loadSchema: dbVersion = schema.loadSchema(db, 'migrate' in argSet) if dbVersion < schema.VERSION: # migration failed... print "ERROR: schema migration has failed from %s to %s" % ( dbVersion, schema.VERSION) if 'migrate' in argSet: logMe(1, "Schema migration complete", dbVersion) sys.exit(0) netRepos = NetworkRepositoryServer(cfg, baseUrl) reqClass.netRepos = proxy.SimpleRepositoryFilter( cfg, baseUrl, netRepos) reqClass.restHandler = None if cfg.baseUri: global cresthooks if cresthooks is None: # we haven't tried to import cresthooks yet - let's give # it a try try: from crest import webhooks as cresthooks except ImportError, e: print 'warning: failed to import crest:', str(e) # fail - let's not try again by setting cresthooks to # False instead of None cresthooks = False if cresthooks: reqClass.restUri = cfg.baseUri + '/api'
def _loadCfg(self): """Load configuration and construct repository objects.""" cfg = self.cfg req = self.request if cfg.repositoryDB: if cfg.proxyContentsDir: raise ConfigurationError("Exactly one of repositoryDB or " "proxyContentsDir must be set.") for name in ('contentsDir', 'serverName'): if not cfg[name]: raise ConfigurationError("%s must be set." % name) else: if not cfg.proxyContentsDir: raise ConfigurationError("Exactly one of repositoryDB or " "proxyContentsDir must be set.") if os.path.realpath(cfg.tmpDir) != cfg.tmpDir: raise ConfigurationError("tmpDir must not contain symbolic links.") self._useForwardedHeaders = self._getEnvBool('use_forwarded_headers', False) if self._useForwardedHeaders: for key in ('x-forwarded-scheme', 'x-forwarded-proto'): if req.headers.get(key): req.scheme = req.headers[key] break for key in ('x-forwarded-host', 'x-forwarded-server'): if req.headers.get(key): req.host = req.headers[key] break self.isSecure = req.scheme == 'https' if req.environ.get('PYTHONPATH'): # Allow SetEnv to propagate, so that commit hooks can have the # proper environment os.environ['PYTHONPATH'] = req.environ['PYTHONPATH'] for mountPoint in [ req.environ.get('conary.netrepos.mount_point'), cfg.baseUri, 'conary' ]: if mountPoint is not None: break for elem in mountPoint.split('/'): if not elem: continue if self.request.path_info_pop() != elem: raise web_exc.HTTPNotFound( "Path %s is not handled by this application." % self.request.script_name) urlBase = req.application_url if cfg.closed: # Closed repository -- returns an exception for all requests self.repositoryServer = netserver.ClosedRepositoryServer(cfg) self.shimServer = self.repositoryServer elif cfg.proxyContentsDir: # Caching proxy (no repository) self.repositoryServer = None self.shimServer = None self.proxyServer = proxy.ProxyRepositoryServer(cfg, urlBase) else: # Full repository with optional changeset cache self.repositoryServer = netserver.NetworkRepositoryServer( cfg, urlBase) self.shimServer = shimclient.NetworkRepositoryServer( cfg, urlBase, db=self.repositoryServer.db) if self.repositoryServer: self.proxyServer = proxy.SimpleRepositoryFilter( cfg, urlBase, self.repositoryServer) self.contentsStore = self.repositoryServer.repos.contentsStore
class HttpRequestsSubclass(server.HttpRequests): tmpDir = cfg.tmpDir netRepos = proxy.SimpleRepositoryFilter(cfg, baseUrl, netServer) restHandler = None
def _handler(req): log.setupLogging(consoleLevel=logging.INFO, consoleFormat='apache') # Keep CONARY_LOG entries from being double-logged log.logger.handlers = [] repName = req.filename if repName in repositories: repServer, proxyServer, restHandler = repositories[repName] else: cfg = netserver.ServerConfig() cfg.read(req.filename) # Throw away any subdir portion. if cfg.baseUri: baseUri = cfg.baseUri else: baseUri = req.uri[:-len(req.path_info)] + '/' urlBase = "%%(protocol)s://%s:%%(port)d" % \ (req.server.server_hostname) + baseUri if not cfg.repositoryDB and not cfg.proxyContentsDir: log.error("repositoryDB or proxyContentsDir is required in %s" % req.filename) return apache.HTTP_INTERNAL_SERVER_ERROR elif cfg.repositoryDB and cfg.proxyContentsDir: log.error( "only one of repositoryDB or proxyContentsDir may be specified " "in %s" % req.filename) return apache.HTTP_INTERNAL_SERVER_ERROR if cfg.repositoryDB: if not cfg.contentsDir: log.error("contentsDir is required in %s" % req.filename) return apache.HTTP_INTERNAL_SERVER_ERROR elif not cfg.serverName: log.error("serverName is required in %s" % req.filename) return apache.HTTP_INTERNAL_SERVER_ERROR if os.path.realpath(cfg.tmpDir) != cfg.tmpDir: log.error("tmpDir cannot include symbolic links") if cfg.closed: # Closed repository repServer = netserver.ClosedRepositoryServer(cfg) proxyServer = proxy.SimpleRepositoryFilter(cfg, urlBase, repServer) restHandler = None elif cfg.proxyContentsDir: # Caching proxy repServer = None proxyServer = proxy.ProxyRepositoryServer(cfg, urlBase) restHandler = None else: # Full repository with changeset cache repServer = netserver.NetworkRepositoryServer(cfg, urlBase) proxyServer = proxy.SimpleRepositoryFilter(cfg, urlBase, repServer) if cresthooks and cfg.baseUri: restUri = cfg.baseUri + '/api' restHandler = cresthooks.ApacheHandler(restUri, repServer) else: restHandler = None repositories[repName] = repServer, proxyServer, restHandler port = req.connection.local_addr[1] # newer versions of mod_python provide a req.is_https() method secure = (req.subprocess_env.get('HTTPS', 'off').lower() == 'on') method = req.method.upper() try: try: # reopen database connections early to make sure crest gets a # working database connection if repServer: repServer.reopen() if method == "POST": return post(port, secure, proxyServer, req, repServer=repServer) elif method == "GET": return get(port, secure, proxyServer, req, restHandler, repServer=repServer) elif method == "PUT": return putFile(port, secure, proxyServer, req) else: return apache.HTTP_METHOD_NOT_ALLOWED finally: # Free temporary resources used by the repserver # e.g. pooled DB connections. if repServer: repServer.reset() except apache.SERVER_RETURN: # if the exception was an apache server return code, # re-raise it and let mod_python handle it. raise except IOError, e: # ignore when the client hangs up on us if str(e).endswith('client closed connection.'): pass else: raise