diff --git a/CHANGES/4917.feature b/CHANGES/4917.feature new file mode 100644 index 00000000000..5aec061a723 --- /dev/null +++ b/CHANGES/4917.feature @@ -0,0 +1 @@ +Enable the gunicorn applications for pulp-api and pulp-content to load configs from a "gunicorn.conf.py" file. diff --git a/pulpcore/app/entrypoint.py b/pulpcore/app/entrypoint.py index d99ea268276..d29df76a299 100644 --- a/pulpcore/app/entrypoint.py +++ b/pulpcore/app/entrypoint.py @@ -9,7 +9,7 @@ from django.db import connection from django.db.utils import InterfaceError, OperationalError from gunicorn.workers.sync import SyncWorker -from gunicorn.app.base import BaseApplication +from gunicorn.app.base import Application from pulpcore.app.apps import pulp_plugin_configs @@ -80,18 +80,29 @@ def run(self): self.api_app_status.delete() -class PulpcoreApiApplication(BaseApplication): +class PulpcoreApiApplication(Application): def __init__(self, options): self.options = options or {} super().__init__() + def init(self, *args, **kwargs): + """ + A hook for setting application-specific configs, which we instead do below in load_config + where it's non-overridable. + """ + pass + def load_config(self): + # Load default gunicorn configs, including reading from the default config file. + super().load_config() + # Override with settings that we've specified in the startup script. [ self.cfg.set(key.lower(), value) for key, value in self.options.items() if value is not None ] self.cfg.set("default_proc_name", "pulpcore-api") + self.cfg.set("threads", "1") # We don't use a threaded worker... self.cfg.set("worker_class", PulpApiWorker.__module__ + "." + PulpApiWorker.__qualname__) def load(self): diff --git a/pulpcore/content/entrypoint.py b/pulpcore/content/entrypoint.py index e158d11652d..c7fe77ad30d 100644 --- a/pulpcore/content/entrypoint.py +++ b/pulpcore/content/entrypoint.py @@ -1,19 +1,30 @@ import click -from gunicorn.app.base import BaseApplication +from gunicorn.app.base import Application -class PulpcoreContentApplication(BaseApplication): +class PulpcoreContentApplication(Application): def __init__(self, options): self.options = options or {} super().__init__() + def init(self, *args, **kwargs): + """ + A hook for setting application-specific configs, which we instead do below in load_config + where it's non-overridable. + """ + pass + def load_config(self): + # Load default gunicorn configs, including reading from the default config file. + super().load_config() + # Override with settings that we've specified in the startup script. [ self.cfg.set(key.lower(), value) for key, value in self.options.items() if value is not None ] self.cfg.set("default_proc_name", "pulpcore-content") + self.cfg.set("threads", "1") # We don't use a threaded worker... self.cfg.set("worker_class", "aiohttp.GunicornWebWorker") def load(self):