def start(self, imports=None): """Start cherryd in a subprocess.""" portend.free(self.host, self.port, timeout=1) args = [ '-m', 'cherrypy.__main__', # __main__ is needed for `-m` in Python 2.6 '-c', self.config_file, '-p', self.pid_file, ] """ Command for running cherryd server with autoreload enabled Using ``` ['-c', "__requires__ = 'CherryPy'; \ import pkg_resources, re, sys; \ sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0]); \ sys.exit(\ pkg_resources.load_entry_point(\ 'CherryPy', 'console_scripts', 'cherryd')())"] ``` doesn't work as it's impossible to reconstruct the `-c`'s contents. Ref: https://github.com/cherrypy/cherrypy/issues/1545 """ if not isinstance(imports, (list, tuple)): imports = [imports] for i in imports: if i: args.append('-i') args.append(i) if self.daemonize: args.append('-d') env = os.environ.copy() # Make sure we import the cherrypy package in which this module is # defined. grandparentdir = os.path.abspath(os.path.join(thisdir, '..', '..')) if env.get('PYTHONPATH', ''): env['PYTHONPATH'] = os.pathsep.join( (grandparentdir, env['PYTHONPATH'])) else: env['PYTHONPATH'] = grandparentdir self._proc = subprocess.Popen([sys.executable] + args, env=env) if self.wait: self.exit_code = self._proc.wait() else: portend.occupied(self.host, self.port, timeout=5) # Give the engine a wee bit more time to finish STARTING if self.daemonize: time.sleep(2) else: time.sleep(1)
def start(self, imports=None): """Start cherryd in a subprocess.""" portend.free(self.host, self.port, timeout=1) args = [ '-m', 'cherrypy', '-c', self.config_file, '-p', self.pid_file, ] r""" Command for running cherryd server with autoreload enabled Using ``` ['-c', "__requires__ = 'CherryPy'; \ import pkg_resources, re, sys; \ sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0]); \ sys.exit(\ pkg_resources.load_entry_point(\ 'CherryPy', 'console_scripts', 'cherryd')())"] ``` doesn't work as it's impossible to reconstruct the `-c`'s contents. Ref: https://github.com/cherrypy/cherrypy/issues/1545 """ if not isinstance(imports, (list, tuple)): imports = [imports] for i in imports: if i: args.append('-i') args.append(i) if self.daemonize: args.append('-d') env = os.environ.copy() # Make sure we import the cherrypy package in which this module is # defined. grandparentdir = os.path.abspath(os.path.join(thisdir, '..', '..')) if env.get('PYTHONPATH', ''): env['PYTHONPATH'] = os.pathsep.join( (grandparentdir, env['PYTHONPATH'])) else: env['PYTHONPATH'] = grandparentdir self._proc = subprocess.Popen([sys.executable] + args, env=env) if self.wait: self.exit_code = self._proc.wait() else: portend.occupied(self.host, self.port, timeout=5) # Give the engine a wee bit more time to finish STARTING if self.daemonize: time.sleep(2) else: time.sleep(1)
def start(self, port, *args, **config): config.update(self.config) config['server.socket_port'] = port portend.free('localhost', port) server = self[port] = subprocess.Popen((sys.executable, '-m', self.module, '-c', json.dumps(config)) + args) portend.occupied('localhost', port) server.started = time.time() assert not server.poll() return clients.Resource('http://localhost:{}'.format(port))
def check_port_availability(host, port): """ Make sure the port is available for the server to start. """ try: portend.free(host, port, timeout=PORT_AVAILABILITY_CHECK_TIMEOUT) except portend.Timeout: # Port is occupied logger.error("Port {} is occupied.\n" "Please check that you do not have other processes " "running on this port and try again.\n".format(port)) sys.exit(1)
def stop(self): """Stop the HTTP server.""" if self.running: # stop() MUST block until the server is *truly* stopped. self.httpserver.stop() # Wait for the socket to be truly freed. if isinstance(self.bind_addr, tuple): portend.free(*self.bound_addr, timeout=Timeouts.free) self.running = False self.bus.log('HTTP Server %s shut down' % self.httpserver) else: self.bus.log('HTTP Server %s already shut down' % self.httpserver)
def stop(self): """Stop the HTTP server.""" if self.running: # stop() MUST block until the server is *truly* stopped. self.httpserver.stop() # Wait for the socket to be truly freed. if isinstance(self.bind_addr, tuple): portend.free(*self.bound_addr, timeout=Timeouts.free) self.running = False self.bus.log('HTTP Server %s shut down' % self.httpserver) else: self.bus.log('HTTP Server %s already shut down' % self.httpserver)
def check_port_availability(host, port): """ Make sure the port is available for the server to start. """ try: portend.free(host, port, timeout=PORT_AVAILABILITY_CHECK_TIMEOUT) except portend.Timeout: # Bypass check when socket activation is used # https://manpages.debian.org/testing/libsystemd-dev/sd_listen_fds.3.en.html#ENVIRONMENT if not os.environ.get("LISTEN_PID", None): # Port is occupied logger.error("Port {} is occupied.\n" "Please check that you do not have other processes " "running on this port and try again.\n".format(port)) sys.exit(1)
def start(self, imports=None): """Start cherryd in a subprocess.""" portend.free(self.host, self.port, timeout=1) args = [ os.path.join(thisdir, '..', 'cherryd'), '-c', self.config_file, '-p', self.pid_file, ] if not isinstance(imports, (list, tuple)): imports = [imports] for i in imports: if i: args.append('-i') args.append(i) if self.daemonize: args.append('-d') env = os.environ.copy() # Make sure we import the cheroot package in which this module is # defined. grandparentdir = os.path.abspath(os.path.join(thisdir, '..', '..')) if env.get('PYTHONPATH', ''): env['PYTHONPATH'] = os.pathsep.join( (grandparentdir, env['PYTHONPATH'])) else: env['PYTHONPATH'] = grandparentdir self._proc = subprocess.Popen([sys.executable] + args, env=env) if self.wait: self.exit_code = self._proc.wait() else: portend.occupied(self.host, self.port, timeout=5) # Give the engine a wee bit more time to finish STARTING if self.daemonize: time.sleep(2) else: time.sleep(1)
def start(self, imports=None): """Start cherryd in a subprocess.""" portend.free(self.host, self.port, timeout=1) args = [ os.path.join(thisdir, '..', 'cherryd'), '-c', self.config_file, '-p', self.pid_file, ] if not isinstance(imports, (list, tuple)): imports = [imports] for i in imports: if i: args.append('-i') args.append(i) if self.daemonize: args.append('-d') env = os.environ.copy() # Make sure we import the cheroot package in which this module is # defined. grandparentdir = os.path.abspath(os.path.join(thisdir, '..', '..')) if env.get('PYTHONPATH', ''): env['PYTHONPATH'] = os.pathsep.join( (grandparentdir, env['PYTHONPATH'])) else: env['PYTHONPATH'] = grandparentdir self._proc = subprocess.Popen([sys.executable] + args, env=env) if self.wait: self.exit_code = self._proc.wait() else: portend.occupied(self.host, self.port, timeout=5) # Give the engine a wee bit more time to finish STARTING if self.daemonize: time.sleep(2) else: time.sleep(1)
def start(self): """Start the HTTP server.""" if self.running: self.bus.log('Already serving on %s' % self.description) return self.interrupt = None if not self.httpserver: raise ValueError('No HTTP server has been created.') if not os.environ.get('LISTEN_PID', None): # Start the httpserver in a new thread. if isinstance(self.bind_addr, tuple): portend.free(*self.bind_addr, timeout=Timeouts.free) import threading t = threading.Thread(target=self._start_http_thread) t.setName('HTTPServer ' + t.getName()) t.start() self.wait() self.running = True self.bus.log('Serving on %s' % self.description)
def start(self): """Start the HTTP server.""" if self.running: self.bus.log('Already serving on %s' % self.description) return self.interrupt = None if not self.httpserver: raise ValueError('No HTTP server has been created.') if not os.environ.get('LISTEN_PID', None): # Start the httpserver in a new thread. if isinstance(self.bind_addr, tuple): portend.free(*self.bind_addr, timeout=Timeouts.free) import threading t = threading.Thread(target=self._start_http_thread) t.setName('HTTPServer ' + t.getName()) t.start() self.wait() self.running = True self.bus.log('Serving on %s' % self.description)
socket_timeout = dconf.get_property("pkg", "socket_timeout") if not socket_timeout: dconf.set_property("pkg", "socket_timeout", SOCKET_TIMEOUT_DEFAULT) socket_timeout = dconf.get_property("pkg", "socket_timeout") threads = dconf.get_property("pkg", "threads") if not threads: dconf.set_property("pkg", "threads", THREADS_DEFAULT) threads = dconf.get_property("pkg", "threads") # If the program is going to reindex, the port is irrelevant since # the program will not bind to a port. if not exit_ready: try: # Wait for the port to be free, time out in 1 sec. portend.free(address, port, 1.0) except Exception as e: emsg("pkg.depotd: unable to bind to the specified " "port: {0:d}. Reason: {1}".format(port, e)) sys.exit(1) else: # Not applicable if we're not going to serve content dconf.set_property("pkg", "content_root", "") # Any relative paths should be made absolute using pkg_root. 'pkg_root' # is a special property that was added to enable internal deployment of # multiple disparate versions of the pkg.depotd software. pkg_root = dconf.get_property("pkg", "pkg_root") repo_config_file = dconf.get_property("pkg", "cfg_file") if repo_config_file and not os.path.isabs(repo_config_file):
def initialize(options): # HTTPS stuff stolen from sickbeard enable_https = options['enable_https'] https_cert = options['https_cert'] https_cert_chain = options['https_cert_chain'] https_key = options['https_key'] if enable_https: # If either the HTTPS certificate or key do not exist, try to make self-signed ones. if plexpy.CONFIG.HTTPS_CREATE_CERT and \ (not (https_cert and os.path.exists(https_cert)) or not (https_key and os.path.exists(https_key))): if not create_https_certificates(https_cert, https_key): logger.warn( u"Tautulli WebStart :: Unable to create certificate and key. Disabling HTTPS" ) enable_https = False if not (os.path.exists(https_cert) and os.path.exists(https_key)): logger.warn( u"Tautulli WebStart :: Disabled HTTPS because of missing certificate and key." ) enable_https = False options_dict = { 'server.socket_port': options['http_port'], 'server.socket_host': options['http_host'], 'environment': options['http_environment'], 'server.thread_pool': 10, 'tools.encode.on': True, 'tools.encode.encoding': 'utf-8', 'tools.decode.on': True } if plexpy.DEV: options_dict['environment'] = "test_suite" options_dict['engine.autoreload.on'] = True if enable_https: options_dict['server.ssl_certificate'] = https_cert options_dict['server.ssl_certificate_chain'] = https_cert_chain options_dict['server.ssl_private_key'] = https_key protocol = "https" else: protocol = "http" if options['http_proxy']: # Overwrite cherrypy.tools.proxy with our own proxy handler cherrypy.tools.proxy = cherrypy.Tool('before_handler', proxy, priority=1) if options['http_password']: login_allowed = [ "Tautulli admin (username is '%s')" % options['http_username'] ] if plexpy.CONFIG.HTTP_PLEX_ADMIN: login_allowed.append("Plex admin") logger.info( u"Tautulli WebStart :: Web server authentication is enabled: %s.", ' and '.join(login_allowed)) if options['http_basic_auth']: auth_enabled = False basic_auth_enabled = True else: auth_enabled = True basic_auth_enabled = False cherrypy.tools.auth = cherrypy.Tool('before_handler', webauth.check_auth, priority=2) else: auth_enabled = basic_auth_enabled = False if options['http_root'].strip('/'): plexpy.HTTP_ROOT = options[ 'http_root'] = '/' + options['http_root'].strip('/') + '/' else: plexpy.HTTP_ROOT = options['http_root'] = '/' cherrypy.config.update(options_dict) conf = { '/': { 'tools.staticdir.root': os.path.join(plexpy.PROG_DIR, 'data'), 'tools.proxy.on': bool(options['http_proxy']), 'tools.gzip.on': True, 'tools.gzip.mime_types': [ 'text/html', 'text/plain', 'text/css', 'text/javascript', 'application/json', 'application/javascript' ], 'tools.auth.on': auth_enabled, 'tools.auth_basic.on': basic_auth_enabled, 'tools.auth_basic.realm': 'Tautulli web server', 'tools.auth_basic.checkpassword': cherrypy.lib.auth_basic.checkpassword_dict( {options['http_username']: options['http_password']}) }, '/api': { 'tools.auth_basic.on': False }, '/interfaces': { 'tools.staticdir.on': True, 'tools.staticdir.dir': "interfaces", 'tools.caching.on': True, 'tools.caching.force': True, 'tools.caching.delay': 0, 'tools.expires.on': True, 'tools.expires.secs': 60 * 60 * 24 * 30, # 30 days 'tools.sessions.on': False, 'tools.auth.on': False }, '/images': { 'tools.staticdir.on': True, 'tools.staticdir.dir': "interfaces/default/images", 'tools.staticdir.content_types': { 'svg': 'image/svg+xml' }, 'tools.caching.on': True, 'tools.caching.force': True, 'tools.caching.delay': 0, 'tools.expires.on': True, 'tools.expires.secs': 60 * 60 * 24 * 30, # 30 days 'tools.sessions.on': False, 'tools.auth.on': False }, '/css': { 'tools.staticdir.on': True, 'tools.staticdir.dir': "interfaces/default/css", 'tools.caching.on': True, 'tools.caching.force': True, 'tools.caching.delay': 0, 'tools.expires.on': True, 'tools.expires.secs': 60 * 60 * 24 * 30, # 30 days 'tools.sessions.on': False, 'tools.auth.on': False }, '/fonts': { 'tools.staticdir.on': True, 'tools.staticdir.dir': "interfaces/default/fonts", 'tools.caching.on': True, 'tools.caching.force': True, 'tools.caching.delay': 0, 'tools.expires.on': True, 'tools.expires.secs': 60 * 60 * 24 * 30, # 30 days 'tools.sessions.on': False, 'tools.auth.on': False }, '/js': { 'tools.staticdir.on': True, 'tools.staticdir.dir': "interfaces/default/js", 'tools.caching.on': True, 'tools.caching.force': True, 'tools.caching.delay': 0, 'tools.expires.on': True, 'tools.expires.secs': 60 * 60 * 24 * 30, # 30 days 'tools.sessions.on': False, 'tools.auth.on': False }, '/cache': { 'tools.staticdir.on': True, 'tools.staticdir.dir': plexpy.CONFIG.CACHE_DIR, 'tools.caching.on': True, 'tools.caching.force': True, 'tools.caching.delay': 0, 'tools.expires.on': True, 'tools.expires.secs': 60 * 60 * 24 * 30, # 30 days 'tools.sessions.on': False, 'tools.auth.on': False }, #'/pms_image_proxy': { # 'tools.staticdir.on': True, # 'tools.staticdir.dir': os.path.join(plexpy.CONFIG.CACHE_DIR, 'images'), # 'tools.caching.on': True, # 'tools.caching.force': True, # 'tools.caching.delay': 0, # 'tools.expires.on': True, # 'tools.expires.secs': 60 * 60 * 24 * 30, # 30 days # 'tools.auth.on': False, # 'tools.sessions.on': False #}, '/favicon.ico': { 'tools.staticfile.on': True, 'tools.staticfile.filename': os.path.abspath( os.path.join( plexpy.PROG_DIR, 'data/interfaces/default/images/favicon/favicon.ico')), 'tools.caching.on': True, 'tools.caching.force': True, 'tools.caching.delay': 0, 'tools.expires.on': True, 'tools.expires.secs': 60 * 60 * 24 * 30, # 30 days 'tools.sessions.on': False, 'tools.auth.on': False } } # Prevent time-outs #cherrypy.engine.timeout_monitor.unsubscribe() cherrypy.tree.mount(WebInterface(), options['http_root'], config=conf) if plexpy.HTTP_ROOT != '/': cherrypy.tree.mount(BaseRedirect(), '/') try: logger.info( u"Tautulli WebStart :: Starting Tautulli web server on %s://%s:%d%s", protocol, options['http_host'], options['http_port'], options['http_root']) portend.free(str(options['http_host']), options['http_port']) if not plexpy.DEV: cherrypy.server.start() else: cherrypy.engine.signals.subscribe() cherrypy.engine.start() cherrypy.engine.block() except IOError: sys.stderr.write( 'Failed to start on port: %i. Is something else running?\n' % (options['http_port'])) sys.exit(1) cherrypy.server.wait()
def port_free(port, host='localhost'): try: portend.free(host, port, timeout=0.1) except portend.Timeout: return False return True
def test_free_with_immediate_timeout(self, nonlistening_addr, immediate_timeout): host, port = nonlistening_addr[:2] portend.free(host, port, timeout=1.0)
def test_free_with_timeout(self, listening_addr): host, port = listening_addr[:2] with pytest.raises(portend.Timeout): portend.free(*listening_addr[:2], timeout=0.3)
def initialize(options): from speakreader import webauth from speakreader.webserve import WebInterface CONFIG = options['config'] options_dict = { 'server.socket_port': options['http_port'], 'server.socket_host': CONFIG.HTTP_HOST, 'environment': 'production', 'server.thread_pool': 50, 'tools.encode.on': True, 'tools.encode.encoding': 'utf-8', 'tools.decode.on': True } if CONFIG.ENABLE_HTTPS: options_dict['server.ssl_certificate'] = CONFIG.HTTPS_CERT options_dict['server.ssl_certificate_chain'] = CONFIG.HTTPS_CERT_CHAIN options_dict['server.ssl_private_key'] = CONFIG.HTTPS_KEY protocol = "https" else: protocol = "http" if CONFIG.HTTP_PROXY: # Overwrite cherrypy.tools.proxy with our own proxy handler cherrypy.tools.proxy = cherrypy.Tool('before_handler', proxy, priority=1) if CONFIG.HTTP_PASSWORD: login_allowed = [ "SpeakReader admin (username is '%s')" % CONFIG.HTTP_USERNAME ] logger.info("WebStart :: Web server authentication is enabled: %s.", ' and '.join(login_allowed)) if CONFIG.HTTP_BASIC_AUTH: auth_enabled = False basic_auth_enabled = True else: auth_enabled = True basic_auth_enabled = False cherrypy.tools.auth = cherrypy.Tool('before_handler', webauth.check_auth, priority=2) else: auth_enabled = basic_auth_enabled = False cherrypy.config.update(options_dict) conf = { '/': { 'tools.staticdir.root': os.path.join(options['prog_dir'], 'html'), 'tools.proxy.on': bool(CONFIG.HTTP_PROXY), 'tools.gzip.on': True, 'tools.gzip.mime_types': [ 'text/html', 'text/plain', 'text/css', 'text/javascript', 'application/json', 'application/javascript' ], 'tools.auth.on': False, 'tools.auth_basic.on': False, 'tools.sessions.on': True, }, '/manage': { 'tools.staticdir.root': os.path.join(options['prog_dir'], 'html'), 'tools.proxy.on': bool(CONFIG.HTTP_PROXY), 'tools.gzip.on': True, 'tools.gzip.mime_types': [ 'text/html', 'text/plain', 'text/css', 'text/javascript', 'application/json', 'application/javascript' ], 'tools.auth.on': auth_enabled, 'tools.auth_basic.on': basic_auth_enabled, 'tools.auth_basic.realm': 'SpeakReader web server', 'tools.auth_basic.checkpassword': cherrypy.lib.auth_basic.checkpassword_dict( {CONFIG.HTTP_USERNAME: CONFIG.HTTP_PASSWORD}), 'tools.sessions.on': True, }, '/images': { 'tools.staticdir.on': True, 'tools.staticdir.dir': "images", 'tools.staticdir.content_types': { 'svg': 'image/svg+xml' }, 'tools.caching.on': True, 'tools.caching.force': True, 'tools.caching.delay': 0, 'tools.expires.on': True, 'tools.expires.secs': 60 * 60 * 24 * 30, # 30 days 'tools.sessions.on': False, 'tools.auth.on': False }, '/css': { 'tools.staticdir.on': True, 'tools.staticdir.dir': "css", 'tools.caching.on': True, 'tools.caching.force': True, 'tools.caching.delay': 0, 'tools.expires.on': True, 'tools.expires.secs': 60 * 60 * 24 * 30, # 30 days 'tools.sessions.on': False, 'tools.auth.on': False }, '/fonts': { 'tools.staticdir.on': True, 'tools.staticdir.dir': "fonts", 'tools.caching.on': True, 'tools.caching.force': True, 'tools.caching.delay': 0, 'tools.expires.on': True, 'tools.expires.secs': 60 * 60 * 24 * 30, # 30 days 'tools.sessions.on': False, 'tools.auth.on': False }, '/js': { 'tools.staticdir.on': True, 'tools.staticdir.dir': "js", 'tools.caching.on': True, 'tools.caching.force': True, 'tools.caching.delay': 0, 'tools.expires.on': True, 'tools.expires.secs': 60 * 60 * 24 * 30, # 30 days 'tools.sessions.on': False, 'tools.auth.on': False }, '/favicon.ico': { 'tools.staticfile.on': True, 'tools.staticfile.filename': os.path.abspath( os.path.join(options['prog_dir'], '/html/images/favicon/favicon.ico')), 'tools.caching.on': True, 'tools.caching.force': True, 'tools.caching.delay': 0, 'tools.expires.on': True, 'tools.expires.secs': 60 * 60 * 24 * 30, # 30 days 'tools.sessions.on': False, 'tools.auth.on': False } } # Prevent time-outs appTree = cherrypy.tree.mount(WebInterface(), CONFIG.HTTP_ROOT, config=conf) if CONFIG.HTTP_ROOT != '/': cherrypy.tree.mount(BaseRedirect(), '/') try: logger.info("WebStart :: Starting Web Server on %s://%s:%d%s", protocol, CONFIG.HTTP_HOST, options['http_port'], CONFIG.HTTP_ROOT) portend.free(str(CONFIG.HTTP_HOST), options['http_port']) except IOError: sys.stderr.write( 'Failed to start on port: %i. Is something else running?\n' % (options['http_port'])) sys.exit(1) # return appTree
def main(): usage = '\n\n'.join(['usage: prog [options]']) parser = optparse.OptionParser(usage=usage) # get directory that the update server is run from devserver_dir = os.path.dirname(os.path.abspath(sys.argv[0])) default_static_dir = '%s/static' % devserver_dir parser.add_option('--static_dir', metavar='PATH', default=default_static_dir, help='writable static directory') parser.add_option( '--port', default=8080, type='int', help=('port for the dev server to use; if zero, binds to ' 'an arbitrary available port (default: 8080)')) _AddUpdateOptions(parser) (options, _) = parser.parse_args() # Handle options that must be set globally in cherrypy. Do this # work up front, because calls to _Log() below depend on this # initialization. if options.production: cherrypy.config.update({'environment': 'production'}) if not options.logfile: cherrypy.config.update({'log.screen': True}) else: cherrypy.config.update({'log.error_file': '', 'log.access_file': ''}) hdlr = MakeLogHandler(options.logfile) # Pylint can't seem to process these two calls properly # pylint: disable=E1101 cherrypy.log.access_log.addHandler(hdlr) cherrypy.log.error_log.addHandler(hdlr) # pylint: enable=E1101 # set static_dir, from which everything will be served options.static_dir = os.path.realpath(options.static_dir) cache_dir = os.path.join(options.static_dir, 'cache') # If our update server is only supposed to serve payloads, we shouldn't be # mucking with the cache at all. If the update server hadn't previously # generated a cache and is expected, the caller is using it wrong. if os.path.exists(cache_dir): _CleanCache(cache_dir, options.clear_cache) else: os.makedirs(cache_dir) if options.exit: return _Log('Using cache directory %s' % cache_dir) _Log('Serving from %s' % options.static_dir) # We allow global use here to share with cherrypy classes. # pylint: disable=W0603 global updater updater = autoupdate.Autoupdate( static_dir=options.static_dir, urlbase=options.urlbase, forced_image=options.image, payload_path=options.payload, proxy_port=None, src_image=options.src_image, board=options.board, copy_to_static_root=not options.exit, private_key=options.private_key, private_key_for_metadata_hash_signature=( options.private_key_for_metadata_hash_signature), public_key=options.public_key, critical_update=options.critical_update, remote_payload=options.remote_payload, max_updates=options.max_updates, host_log=options.host_log, ) if options.pregenerate_update: updater.PreGenerateUpdate() # Patch CherryPy to support binding to any available port (--port=0). portend.free('::1', options.port, timeout=5) cherrypy.quickstart(DevServerRoot(), config=_GetConfig(options))