|
1 | 1 | from dagster import Field, Noneable, Permissive, StringSource |
2 | 2 | from dagster.core.definitions.executor import check_cross_process_constraints, executor |
3 | 3 | from dagster.core.execution.retries import Retries, get_retries_config |
4 | | -from dagster.utils import merge_dicts |
5 | 4 |
|
6 | | -from .config import CeleryConfig, CeleryK8sJobConfig |
| 5 | +from .config import CeleryConfig |
7 | 6 |
|
8 | 7 | CELERY_CONFIG = { |
9 | 8 | 'broker': Field( |
@@ -93,124 +92,3 @@ def celery_enabled_pipeline(): |
93 | 92 | include=init_context.executor_config.get('include'), |
94 | 93 | retries=Retries.from_config(init_context.executor_config['retries']), |
95 | 94 | ) |
96 | | - |
97 | | - |
98 | | -def celery_k8s_config(): |
99 | | - from dagster_k8s.job import DagsterK8sJobConfig |
100 | | - |
101 | | - # DagsterK8sJobConfig provides config schema for specifying Dagster K8s Jobs |
102 | | - job_config = DagsterK8sJobConfig.config_type() |
103 | | - |
104 | | - additional_config = { |
105 | | - 'load_incluster_config': Field( |
106 | | - bool, |
107 | | - is_required=False, |
108 | | - default_value=True, |
109 | | - description='''Set this value if you are running the launcher within a k8s cluster. If |
110 | | - ``True``, we assume the launcher is running within the target cluster and load config |
111 | | - using ``kubernetes.config.load_incluster_config``. Otherwise, we will use the k8s config |
112 | | - specified in ``kubeconfig_file`` (using ``kubernetes.config.load_kube_config``) or fall |
113 | | - back to the default kubeconfig. Default: ``True``.''', |
114 | | - ), |
115 | | - 'kubeconfig_file': Field( |
116 | | - Noneable(str), |
117 | | - is_required=False, |
118 | | - description='Path to a kubeconfig file to use, if not using default kubeconfig.', |
119 | | - ), |
120 | | - 'job_namespace': Field( |
121 | | - str, |
122 | | - is_required=False, |
123 | | - default_value='default', |
124 | | - description='The namespace into which to launch new jobs. Note that any ' |
125 | | - 'other Kubernetes resources the Job requires (such as the service account) must be ' |
126 | | - 'present in this namespace. Default: ``"default"``', |
127 | | - ), |
128 | | - } |
129 | | - |
130 | | - cfg = merge_dicts(CELERY_CONFIG, job_config) |
131 | | - cfg = merge_dicts(cfg, additional_config) |
132 | | - return cfg |
133 | | - |
134 | | - |
135 | | -@executor(name='celery-k8s', config=celery_k8s_config()) |
136 | | -def celery_k8s_job_executor(init_context): |
137 | | - '''Celery-based executor which launches tasks as Kubernetes Jobs. |
138 | | -
|
139 | | - The Celery executor exposes config settings for the underlying Celery app under |
140 | | - the ``config_source`` key. This config corresponds to the "new lowercase settings" introduced |
141 | | - in Celery version 4.0 and the object constructed from config will be passed to the |
142 | | - :py:class:`celery.Celery` constructor as its ``config_source`` argument. |
143 | | - (See https://docs.celeryproject.org/en/latest/userguide/configuration.html for details.) |
144 | | -
|
145 | | - The executor also exposes the ``broker``, `backend`, and ``include`` arguments to the |
146 | | - :py:class:`celery.Celery` constructor. |
147 | | -
|
148 | | - In the most common case, you may want to modify the ``broker`` and ``backend`` (e.g., to use |
149 | | - Redis instead of RabbitMQ). We expect that ``config_source`` will be less frequently |
150 | | - modified, but that when solid executions are especially fast or slow, or when there are |
151 | | - different requirements around idempotence or retry, it may make sense to execute pipelines |
152 | | - with variations on these settings. |
153 | | -
|
154 | | - If you'd like to configure a Celery Kubernetes Job executor in addition to the |
155 | | - :py:class:`~dagster.default_executors`, you should add it to the ``executor_defs`` defined on a |
156 | | - :py:class:`~dagster.ModeDefinition` as follows: |
157 | | -
|
158 | | - .. code-block:: python |
159 | | -
|
160 | | - from dagster import ModeDefinition, default_executors, pipeline |
161 | | - from dagster_celery import celery_k8s_job_executor |
162 | | -
|
163 | | - @pipeline(mode_defs=[ |
164 | | - ModeDefinition(executor_defs=default_executors + [celery_k8s_job_executor]) |
165 | | - ]) |
166 | | - def celery_enabled_pipeline(): |
167 | | - pass |
168 | | -
|
169 | | - Then you can configure the executor as follows: |
170 | | -
|
171 | | - .. code-block:: YAML |
172 | | -
|
173 | | - execution: |
174 | | - celery-k8s: |
175 | | - config: |
176 | | - job_image: 'my_repo.com/image_name:latest' |
177 | | - job_namespace: 'some-namespace' |
178 | | - broker: 'pyamqp://guest@localhost//' # Optional[str]: The URL of the Celery broker |
179 | | - backend: 'rpc://' # Optional[str]: The URL of the Celery results backend |
180 | | - include: ['my_module'] # Optional[List[str]]: Modules every worker should import |
181 | | - config_source: # Dict[str, Any]: Any additional parameters to pass to the |
182 | | - #... # Celery workers. This dict will be passed as the `config_source` |
183 | | - #... # argument of celery.Celery(). |
184 | | -
|
185 | | - Note that the YAML you provide here must align with the configuration with which the Celery |
186 | | - workers on which you hope to run were started. If, for example, you point the executor at a |
187 | | - different broker than the one your workers are listening to, the workers will never be able to |
188 | | - pick up tasks for execution. |
189 | | - ''' |
190 | | - from dagster_k8s.job import DagsterK8sJobConfig |
191 | | - |
192 | | - check_cross_process_constraints(init_context) |
193 | | - |
194 | | - job_config = DagsterK8sJobConfig( |
195 | | - job_image=init_context.executor_config.get('job_image'), |
196 | | - dagster_home=init_context.executor_config.get('dagster_home'), |
197 | | - image_pull_policy=init_context.executor_config.get('image_pull_policy'), |
198 | | - image_pull_secrets=init_context.executor_config.get('image_pull_secrets'), |
199 | | - service_account_name=init_context.executor_config.get('service_account_name'), |
200 | | - instance_config_map=init_context.executor_config.get('instance_config_map'), |
201 | | - postgres_password_secret=init_context.executor_config.get('postgres_password_secret'), |
202 | | - env_config_maps=init_context.executor_config.get('env_config_maps'), |
203 | | - env_secrets=init_context.executor_config.get('env_secrets'), |
204 | | - ) |
205 | | - |
206 | | - return CeleryK8sJobConfig( |
207 | | - broker=init_context.executor_config.get('broker'), |
208 | | - backend=init_context.executor_config.get('backend'), |
209 | | - config_source=init_context.executor_config.get('config_source'), |
210 | | - include=init_context.executor_config.get('include'), |
211 | | - retries=Retries.from_config(init_context.executor_config['retries']), |
212 | | - job_config=job_config, |
213 | | - job_namespace=init_context.executor_config.get('job_namespace'), |
214 | | - load_incluster_config=init_context.executor_config.get('load_incluster_config'), |
215 | | - kubeconfig_file=init_context.executor_config.get('kubeconfig_file'), |
216 | | - ) |
0 commit comments