diff --git a/awx/main/apps.py b/awx/main/apps.py index ed1e4a5abb..16c76e6455 100644 --- a/awx/main/apps.py +++ b/awx/main/apps.py @@ -3,6 +3,7 @@ import os from dispatcherd.config import setup as dispatcher_setup from django.apps import AppConfig +from django.db import connection from django.utils.translation import gettext_lazy as _ from awx.main.utils.common import bypass_in_test, load_all_entry_points_for from awx.main.utils.migration import is_database_synchronized @@ -78,12 +79,27 @@ class MainConfig(AppConfig): cls = entry_point.load() InventorySourceOptions.injectors[entry_point_name] = cls + def configure_dispatcherd(self): + """This implements the default configuration for dispatcherd + + If running the tasking service like awx-manage run_dispatcher, + some additional config will be applied on top of this. + This configuration provides the minimum such that code can submit + tasks to pg_notify to run those tasks. + """ + from awx.main.dispatch.config import get_dispatcherd_config + + if connection.vendor != 'postgresql': + config_dict = get_dispatcherd_config(mock_publish=True) + else: + config_dict = get_dispatcherd_config() + + dispatcher_setup(config_dict) + def ready(self): super().ready() - from awx.main.dispatch.config import get_dispatcherd_config - - dispatcher_setup(get_dispatcherd_config()) + self.configure_dispatcherd() """ Credential loading triggers database operations. There are cases we want to call diff --git a/awx/main/dispatch/config.py b/awx/main/dispatch/config.py index 189653d37b..d4c58c6459 100644 --- a/awx/main/dispatch/config.py +++ b/awx/main/dispatch/config.py @@ -5,7 +5,7 @@ from awx.main.dispatch import get_task_queuename from awx.main.dispatch.pool import get_auto_max_workers -def get_dispatcherd_config(for_service: bool = False) -> dict: +def get_dispatcherd_config(for_service: bool = False, mock_publish: bool = False) -> dict: """Return a dictionary config for dispatcherd Parameters: @@ -24,20 +24,23 @@ def get_dispatcherd_config(for_service: bool = False) -> dict: "process_manager_kwargs": {"preload_modules": ['awx.main.dispatch.hazmat']}, }, "brokers": { - "pg_notify": { - "config": get_pg_notify_params(), - "sync_connection_factory": "ansible_base.lib.utils.db.psycopg_connection_from_django", - "default_publish_channel": settings.CLUSTER_HOST_ID, # used for debugging commands - }, "socket": {"socket_path": settings.DISPATCHERD_DEBUGGING_SOCKFILE}, }, - "publish": { - "default_control_broker": "socket", - "default_broker": "pg_notify", - }, + "publish": {"default_control_broker": "socket"}, "worker": {"worker_cls": "awx.main.dispatch.worker.dispatcherd.AWXTaskWorker"}, } + if mock_publish: + config["brokers"]["noop"] = {} + config["publish"]["default_broker"] = "noop" + else: + config["brokers"]["pg_notify"] = { + "config": get_pg_notify_params(), + "sync_connection_factory": "ansible_base.lib.utils.db.psycopg_connection_from_django", + "default_publish_channel": settings.CLUSTER_HOST_ID, # used for debugging commands + } + config["publish"]["default_broker"] = "pg_notify" + if for_service: config["producers"] = { "ScheduledProducer": {"task_schedule": settings.DISPATCHER_SCHEDULE}, diff --git a/awx/main/tests/conftest.py b/awx/main/tests/conftest.py index a6f7b5aca9..71e9637ed9 100644 --- a/awx/main/tests/conftest.py +++ b/awx/main/tests/conftest.py @@ -209,12 +209,6 @@ def mock_get_event_queryset_no_job_created(): yield _fixture -@pytest.fixture(scope='session', autouse=True) -def mock_dispatcherd_publish(): - with mock.patch('dispatcherd.brokers.pg_notify.Broker.publish_message', autospec=True): - yield - - @pytest.fixture def mock_me(): "Allows Instance.objects.me() to work without touching the database" diff --git a/awx_collection/test/awx/conftest.py b/awx_collection/test/awx/conftest.py index a4bf207c20..6de5ed9c25 100644 --- a/awx_collection/test/awx/conftest.py +++ b/awx_collection/test/awx/conftest.py @@ -18,7 +18,7 @@ import pytest from ansible.module_utils.six import raise_from from ansible_base.rbac.models import RoleDefinition, DABPermission -from awx.main.tests.conftest import load_all_credentials, mock_dispatcherd_publish # noqa: F401; pylint: disable=unused-import +from awx.main.tests.conftest import load_all_credentials # noqa: F401; pylint: disable=unused-import from awx.main.tests.functional.conftest import _request from awx.main.tests.functional.conftest import credentialtype_scm, credentialtype_ssh # noqa: F401; pylint: disable=unused-import from awx.main.models import ( diff --git a/requirements/requirements.txt b/requirements/requirements.txt index 2c3c9a2cf6..327e3a8d12 100644 --- a/requirements/requirements.txt +++ b/requirements/requirements.txt @@ -128,7 +128,7 @@ deprecated==1.2.15 # opentelemetry-exporter-otlp-proto-http # opentelemetry-semantic-conventions # pygithub -dispatcherd==2025.5.12 +dispatcherd==2025.5.21 # via -r /awx_devel/requirements/requirements.in distro==1.9.0 # via -r /awx_devel/requirements/requirements.in