apache-airflow-providers-cncf-kubernetes 10.0.0__py3-none-any.whl → 10.0.1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of apache-airflow-providers-cncf-kubernetes might be problematic. Click here for more details.

Files changed (25) hide show
  1. airflow/providers/cncf/kubernetes/__init__.py +1 -1
  2. airflow/providers/cncf/kubernetes/backcompat/__init__.py +17 -0
  3. airflow/providers/cncf/kubernetes/cli/kubernetes_command.py +12 -4
  4. airflow/providers/cncf/kubernetes/decorators/kubernetes.py +2 -1
  5. airflow/providers/cncf/kubernetes/executors/kubernetes_executor.py +44 -21
  6. airflow/providers/cncf/kubernetes/executors/kubernetes_executor_types.py +14 -4
  7. airflow/providers/cncf/kubernetes/executors/kubernetes_executor_utils.py +30 -3
  8. airflow/providers/cncf/kubernetes/executors/local_kubernetes_executor.py +14 -1
  9. airflow/providers/cncf/kubernetes/get_provider_info.py +2 -1
  10. airflow/providers/cncf/kubernetes/hooks/kubernetes.py +2 -1
  11. airflow/providers/cncf/kubernetes/kubernetes_helper_functions.py +6 -3
  12. airflow/providers/cncf/kubernetes/operators/job.py +2 -2
  13. airflow/providers/cncf/kubernetes/operators/pod.py +2 -2
  14. airflow/providers/cncf/kubernetes/operators/resource.py +2 -1
  15. airflow/providers/cncf/kubernetes/operators/spark_kubernetes.py +0 -2
  16. airflow/providers/cncf/kubernetes/pod_generator.py +8 -7
  17. airflow/providers/cncf/kubernetes/sensors/spark_kubernetes.py +2 -1
  18. airflow/providers/cncf/kubernetes/triggers/job.py +2 -1
  19. airflow/providers/cncf/kubernetes/triggers/pod.py +2 -1
  20. airflow/providers/cncf/kubernetes/utils/k8s_resource_iterator.py +2 -1
  21. airflow/providers/cncf/kubernetes/utils/pod_manager.py +2 -2
  22. {apache_airflow_providers_cncf_kubernetes-10.0.0.dist-info → apache_airflow_providers_cncf_kubernetes-10.0.1.dist-info}/METADATA +6 -6
  23. {apache_airflow_providers_cncf_kubernetes-10.0.0.dist-info → apache_airflow_providers_cncf_kubernetes-10.0.1.dist-info}/RECORD +25 -25
  24. {apache_airflow_providers_cncf_kubernetes-10.0.0.dist-info → apache_airflow_providers_cncf_kubernetes-10.0.1.dist-info}/WHEEL +0 -0
  25. {apache_airflow_providers_cncf_kubernetes-10.0.0.dist-info → apache_airflow_providers_cncf_kubernetes-10.0.1.dist-info}/entry_points.txt +0 -0
@@ -29,7 +29,7 @@ from airflow import __version__ as airflow_version
29
29
 
30
30
  __all__ = ["__version__"]
31
31
 
32
- __version__ = "10.0.0"
32
+ __version__ = "10.0.1"
33
33
 
34
34
  if packaging.version.parse(packaging.version.parse(airflow_version).base_version) < packaging.version.parse(
35
35
  "2.8.0"
@@ -14,3 +14,20 @@
14
14
  # KIND, either express or implied. See the License for the
15
15
  # specific language governing permissions and limitations
16
16
  # under the License.
17
+
18
+ from __future__ import annotations
19
+
20
+
21
+ def get_logical_date_key() -> str:
22
+ """
23
+ Get the key for execution/logical date for the appropriate Airflow version.
24
+
25
+ This is done by detecting the CLI argument name. There are various ways to
26
+ do this, but the CLI key name has a very small import footprint (especially
27
+ compared to importing ORM models).
28
+ """
29
+ from airflow.cli import cli_config
30
+
31
+ if hasattr(cli_config, "ARG_LOGICAL_DATE"):
32
+ return "logical_date"
33
+ return "execution_date"
@@ -25,7 +25,9 @@ from datetime import datetime, timedelta
25
25
  from kubernetes import client
26
26
  from kubernetes.client.api_client import ApiClient
27
27
  from kubernetes.client.rest import ApiException
28
+ from packaging.version import Version
28
29
 
30
+ from airflow import __version__ as airflow_version
29
31
  from airflow.models import DagRun, TaskInstance
30
32
  from airflow.providers.cncf.kubernetes import pod_generator
31
33
  from airflow.providers.cncf.kubernetes.executors.kubernetes_executor import KubeConfig
@@ -36,15 +38,21 @@ from airflow.utils import cli as cli_utils, yaml
36
38
  from airflow.utils.cli import get_dag
37
39
  from airflow.utils.providers_configuration_loader import providers_configuration_loaded
38
40
 
41
+ AIRFLOW_VERSION = Version(airflow_version)
42
+ AIRFLOW_V_3_0_PLUS = Version(AIRFLOW_VERSION.base_version) >= Version("3.0.0")
43
+
39
44
 
40
45
  @cli_utils.action_cli
41
46
  @providers_configuration_loaded
42
47
  def generate_pod_yaml(args):
43
48
  """Generate yaml files for each task in the DAG. Used for testing output of KubernetesExecutor."""
44
- execution_date = args.execution_date
49
+ logical_date = args.logical_date if AIRFLOW_V_3_0_PLUS else args.execution_date
45
50
  dag = get_dag(subdir=args.subdir, dag_id=args.dag_id)
46
51
  yaml_output_path = args.output_path
47
- dr = DagRun(dag.dag_id, execution_date=execution_date)
52
+ if AIRFLOW_V_3_0_PLUS:
53
+ dr = DagRun(dag.dag_id, logical_date=logical_date)
54
+ else:
55
+ dr = DagRun(dag.dag_id, execution_date=logical_date)
48
56
  kube_config = KubeConfig()
49
57
  for task in dag.tasks:
50
58
  ti = TaskInstance(task, None)
@@ -55,7 +63,7 @@ def generate_pod_yaml(args):
55
63
  pod_id=create_unique_id(args.dag_id, ti.task_id),
56
64
  try_number=ti.try_number,
57
65
  kube_image=kube_config.kube_image,
58
- date=ti.execution_date,
66
+ date=ti.logical_date if AIRFLOW_V_3_0_PLUS else ti.execution_date,
59
67
  args=ti.command_as_list(),
60
68
  pod_override_object=PodGenerator.from_obj(ti.executor_config),
61
69
  scheduler_job_id="worker-config",
@@ -64,7 +72,7 @@ def generate_pod_yaml(args):
64
72
  with_mutation_hook=True,
65
73
  )
66
74
  api_client = ApiClient()
67
- date_string = pod_generator.datetime_to_label_safe_datestring(execution_date)
75
+ date_string = pod_generator.datetime_to_label_safe_datestring(logical_date)
68
76
  yaml_file_name = f"{args.dag_id}_{ti.task_id}_{date_string}.yml"
69
77
  os.makedirs(os.path.dirname(yaml_output_path + "/airflow_yaml_output/"), exist_ok=True)
70
78
  with open(yaml_output_path + "/airflow_yaml_output/" + yaml_file_name, "w") as output:
@@ -20,9 +20,10 @@ import base64
20
20
  import os
21
21
  import pickle
22
22
  import uuid
23
+ from collections.abc import Sequence
23
24
  from shlex import quote
24
25
  from tempfile import TemporaryDirectory
25
- from typing import TYPE_CHECKING, Callable, Sequence
26
+ from typing import TYPE_CHECKING, Callable
26
27
 
27
28
  import dill
28
29
  from kubernetes.client import models as k8s
@@ -30,17 +30,24 @@ import logging
30
30
  import multiprocessing
31
31
  import time
32
32
  from collections import Counter, defaultdict
33
+ from collections.abc import Sequence
33
34
  from contextlib import suppress
34
35
  from datetime import datetime
35
36
  from queue import Empty, Queue
36
- from typing import TYPE_CHECKING, Any, Sequence
37
+ from typing import TYPE_CHECKING, Any
37
38
 
39
+ from deprecated import deprecated
38
40
  from kubernetes.dynamic import DynamicClient
39
41
  from sqlalchemy import or_, select, update
40
42
 
43
+ try:
44
+ from airflow.cli.cli_config import ARG_LOGICAL_DATE
45
+ except ImportError: # 2.x compatibility.
46
+ from airflow.cli.cli_config import ( # type: ignore[attr-defined, no-redef]
47
+ ARG_EXECUTION_DATE as ARG_LOGICAL_DATE,
48
+ )
41
49
  from airflow.cli.cli_config import (
42
50
  ARG_DAG_ID,
43
- ARG_EXECUTION_DATE,
44
51
  ARG_OUTPUT_PATH,
45
52
  ARG_SUBDIR,
46
53
  ARG_VERBOSE,
@@ -51,6 +58,7 @@ from airflow.cli.cli_config import (
51
58
  positive_int,
52
59
  )
53
60
  from airflow.configuration import conf
61
+ from airflow.exceptions import AirflowProviderDeprecationWarning
54
62
  from airflow.executors.base_executor import BaseExecutor
55
63
  from airflow.executors.executor_constants import KUBERNETES_EXECUTOR
56
64
  from airflow.providers.cncf.kubernetes.executors.kubernetes_executor_types import (
@@ -118,7 +126,7 @@ KUBERNETES_COMMANDS = (
118
126
  help="Generate YAML files for all tasks in DAG. Useful for debugging tasks without "
119
127
  "launching into a cluster",
120
128
  func=lazy_load_command("airflow.providers.cncf.kubernetes.cli.kubernetes_command.generate_pod_yaml"),
121
- args=(ARG_DAG_ID, ARG_EXECUTION_DATE, ARG_SUBDIR, ARG_OUTPUT_PATH, ARG_VERBOSE),
129
+ args=(ARG_DAG_ID, ARG_LOGICAL_DATE, ARG_SUBDIR, ARG_OUTPUT_PATH, ARG_VERBOSE),
122
130
  ),
123
131
  )
124
132
 
@@ -605,6 +613,10 @@ class KubernetesExecutor(BaseExecutor):
605
613
  tis_to_flush.extend(_iter_tis_to_flush())
606
614
  return tis_to_flush
607
615
 
616
+ @deprecated(
617
+ reason="Replaced by function `revoke_task`. Upgrade airflow core to make this go away.",
618
+ category=AirflowProviderDeprecationWarning,
619
+ )
608
620
  def cleanup_stuck_queued_tasks(self, tis: list[TaskInstance]) -> list[str]:
609
621
  """
610
622
  Handle remnants of tasks that were failed because they were stuck in queued.
@@ -616,28 +628,39 @@ class KubernetesExecutor(BaseExecutor):
616
628
  :param tis: List of Task Instances to clean up
617
629
  :return: List of readable task instances for a warning message
618
630
  """
631
+ reprs = []
632
+ for ti in tis:
633
+ reprs.append(repr(ti))
634
+ self.revoke_task(ti=ti)
635
+ self.fail(ti.key)
636
+ return reprs
637
+
638
+ def revoke_task(self, *, ti: TaskInstance):
639
+ """
640
+ Revoke task that may be running.
641
+
642
+ :param ti: task instance to revoke
643
+ """
619
644
  if TYPE_CHECKING:
620
645
  assert self.kube_client
621
646
  assert self.kube_scheduler
622
- readable_tis: list[str] = []
623
- if not tis:
624
- return readable_tis
647
+ self.running.discard(ti.key)
648
+ self.queued_tasks.pop(ti.key, None)
625
649
  pod_combined_search_str_to_pod_map = self.get_pod_combined_search_str_to_pod_map()
626
- for ti in tis:
627
- # Build the pod selector
628
- base_label_selector = f"dag_id={ti.dag_id},task_id={ti.task_id}"
629
- if ti.map_index >= 0:
630
- # Old tasks _couldn't_ be mapped, so we don't have to worry about compat
631
- base_label_selector += f",map_index={ti.map_index}"
632
-
633
- search_str = f"{base_label_selector},run_id={ti.run_id}"
634
- pod = pod_combined_search_str_to_pod_map.get(search_str, None)
635
- if not pod:
636
- self.log.warning("Cannot find pod for ti %s", ti)
637
- continue
638
- readable_tis.append(repr(ti))
639
- self.kube_scheduler.delete_pod(pod_name=pod.metadata.name, namespace=pod.metadata.namespace)
640
- return readable_tis
650
+ # Build the pod selector
651
+ base_label_selector = f"dag_id={ti.dag_id},task_id={ti.task_id}"
652
+ if ti.map_index >= 0:
653
+ # Old tasks _couldn't_ be mapped, so we don't have to worry about compat
654
+ base_label_selector += f",map_index={ti.map_index}"
655
+
656
+ search_str = f"{base_label_selector},run_id={ti.run_id}"
657
+ pod = pod_combined_search_str_to_pod_map.get(search_str, None)
658
+ if not pod:
659
+ self.log.warning("Cannot find pod for ti %s", ti)
660
+ return
661
+
662
+ self.kube_scheduler.patch_pod_revoked(pod_name=pod.metadata.name, namespace=pod.metadata.namespace)
663
+ self.kube_scheduler.delete_pod(pod_name=pod.metadata.name, namespace=pod.metadata.namespace)
641
664
 
642
665
  def adopt_launched_task(
643
666
  self,
@@ -16,7 +16,7 @@
16
16
  # under the License.
17
17
  from __future__ import annotations
18
18
 
19
- from typing import TYPE_CHECKING, Any, Dict, Optional, Tuple, Union
19
+ from typing import TYPE_CHECKING, Any, Optional, Union
20
20
 
21
21
  ADOPTED = "adopted"
22
22
  if TYPE_CHECKING:
@@ -25,13 +25,23 @@ if TYPE_CHECKING:
25
25
  from airflow.utils.state import TaskInstanceState
26
26
 
27
27
  # TaskInstance key, command, configuration, pod_template_file
28
- KubernetesJobType = Tuple[TaskInstanceKey, CommandType, Any, Optional[str]]
28
+ KubernetesJobType = tuple[TaskInstanceKey, CommandType, Any, Optional[str]]
29
29
 
30
30
  # key, pod state, pod_name, namespace, resource_version
31
- KubernetesResultsType = Tuple[TaskInstanceKey, Optional[Union[TaskInstanceState, str]], str, str, str]
31
+ KubernetesResultsType = tuple[TaskInstanceKey, Optional[Union[TaskInstanceState, str]], str, str, str]
32
32
 
33
33
  # pod_name, namespace, pod state, annotations, resource_version
34
- KubernetesWatchType = Tuple[str, str, Optional[Union[TaskInstanceState, str]], Dict[str, str], str]
34
+ KubernetesWatchType = tuple[str, str, Optional[Union[TaskInstanceState, str]], dict[str, str], str]
35
35
 
36
36
  ALL_NAMESPACES = "ALL_NAMESPACES"
37
37
  POD_EXECUTOR_DONE_KEY = "airflow_executor_done"
38
+
39
+ POD_REVOKED_KEY = "airflow_pod_revoked"
40
+ """Label to indicate pod revoked by executor.
41
+
42
+ When executor the executor revokes a task, the pod deletion is the result of
43
+ the revocation. So we don't want it to process that as an external deletion.
44
+ So we want events on a revoked pod to be ignored.
45
+
46
+ :meta private:
47
+ """
@@ -28,10 +28,12 @@ from kubernetes.client.rest import ApiException
28
28
  from urllib3.exceptions import ReadTimeoutError
29
29
 
30
30
  from airflow.exceptions import AirflowException
31
+ from airflow.providers.cncf.kubernetes.backcompat import get_logical_date_key
31
32
  from airflow.providers.cncf.kubernetes.executors.kubernetes_executor_types import (
32
33
  ADOPTED,
33
34
  ALL_NAMESPACES,
34
35
  POD_EXECUTOR_DONE_KEY,
36
+ POD_REVOKED_KEY,
35
37
  )
36
38
  from airflow.providers.cncf.kubernetes.kube_client import get_kube_client
37
39
  from airflow.providers.cncf.kubernetes.kubernetes_helper_functions import (
@@ -150,6 +152,7 @@ class KubernetesJobWatcher(multiprocessing.Process, LoggingMixin):
150
152
  kwargs["_request_timeout"] = client_timeout
151
153
  kwargs["timeout_seconds"] = server_conn_timeout
152
154
 
155
+ logical_date_key = get_logical_date_key()
153
156
  for event in self._pod_events(kube_client=kube_client, query_kwargs=kwargs):
154
157
  task = event["object"]
155
158
  self.log.debug("Event: %s had an event of type %s", task.metadata.name, event["type"])
@@ -159,7 +162,7 @@ class KubernetesJobWatcher(multiprocessing.Process, LoggingMixin):
159
162
  task_instance_related_annotations = {
160
163
  "dag_id": annotations["dag_id"],
161
164
  "task_id": annotations["task_id"],
162
- "execution_date": annotations.get("execution_date"),
165
+ logical_date_key: annotations.get(logical_date_key),
163
166
  "run_id": annotations.get("run_id"),
164
167
  "try_number": annotations["try_number"],
165
168
  }
@@ -203,9 +206,13 @@ class KubernetesJobWatcher(multiprocessing.Process, LoggingMixin):
203
206
  resource_version: str,
204
207
  event: Any,
205
208
  ) -> None:
209
+ """Process status response."""
206
210
  pod = event["object"]
211
+
212
+ if POD_REVOKED_KEY in pod.metadata.labels.keys():
213
+ return
214
+
207
215
  annotations_string = annotations_for_logging_task_metadata(annotations)
208
- """Process status response."""
209
216
  if event["type"] == "DELETED" and not pod.metadata.deletion_timestamp:
210
217
  # This will happen only when the task pods are adopted by another executor.
211
218
  # So, there is no change in the pod state.
@@ -431,7 +438,7 @@ class AirflowKubernetesScheduler(LoggingMixin):
431
438
  def delete_pod(self, pod_name: str, namespace: str) -> None:
432
439
  """Delete Pod from a namespace; does not raise if it does not exist."""
433
440
  try:
434
- self.log.debug("Deleting pod %s in namespace %s", pod_name, namespace)
441
+ self.log.info("Deleting pod %s in namespace %s", pod_name, namespace)
435
442
  self.kube_client.delete_namespaced_pod(
436
443
  pod_name,
437
444
  namespace,
@@ -443,6 +450,26 @@ class AirflowKubernetesScheduler(LoggingMixin):
443
450
  if str(e.status) != "404":
444
451
  raise
445
452
 
453
+ def patch_pod_revoked(self, *, pod_name: str, namespace: str):
454
+ """
455
+ Patch the pod with a label that ensures it's ignored by the kubernetes watcher.
456
+
457
+ :meta private:
458
+ """
459
+ self.log.info(
460
+ "Patching pod %s in namespace %s to note that we are revoking the task.",
461
+ pod_name,
462
+ namespace,
463
+ )
464
+ try:
465
+ self.kube_client.patch_namespaced_pod(
466
+ name=pod_name,
467
+ namespace=namespace,
468
+ body={"metadata": {"labels": {POD_REVOKED_KEY: "True"}}},
469
+ )
470
+ except ApiException:
471
+ self.log.warning("Failed to patch pod %s with pod revoked key.", pod_name, exc_info=True)
472
+
446
473
  def patch_pod_executor_done(self, *, pod_name: str, namespace: str):
447
474
  """Add a "done" annotation to ensure we don't continually adopt pods."""
448
475
  self.log.debug("Patching pod %s in namespace %s to mark it as done", pod_name, namespace)
@@ -17,9 +17,13 @@
17
17
  # under the License.
18
18
  from __future__ import annotations
19
19
 
20
- from typing import TYPE_CHECKING, Sequence
20
+ from collections.abc import Sequence
21
+ from typing import TYPE_CHECKING
22
+
23
+ from deprecated import deprecated
21
24
 
22
25
  from airflow.configuration import conf
26
+ from airflow.exceptions import AirflowProviderDeprecationWarning
23
27
  from airflow.executors.base_executor import BaseExecutor
24
28
  from airflow.providers.cncf.kubernetes.executors.kubernetes_executor import KubernetesExecutor
25
29
 
@@ -230,12 +234,21 @@ class LocalKubernetesExecutor(BaseExecutor):
230
234
  *self.kubernetes_executor.try_adopt_task_instances(kubernetes_tis),
231
235
  ]
232
236
 
237
+ @deprecated(
238
+ reason="Replaced by function `revoke_task`. Upgrade airflow core to make this go away.",
239
+ category=AirflowProviderDeprecationWarning,
240
+ action="ignore", # ignoring since will get warning from the nested executors
241
+ )
233
242
  def cleanup_stuck_queued_tasks(self, tis: list[TaskInstance]) -> list[str]:
234
243
  # LocalExecutor doesn't have a cleanup_stuck_queued_tasks method, so we
235
244
  # will only run KubernetesExecutor's
236
245
  kubernetes_tis = [ti for ti in tis if ti.queue == self.KUBERNETES_QUEUE]
237
246
  return self.kubernetes_executor.cleanup_stuck_queued_tasks(kubernetes_tis)
238
247
 
248
+ def revoke_task(self, *, ti: TaskInstance):
249
+ if ti.queue == self.KUBERNETES_QUEUE:
250
+ self.kubernetes_executor.revoke_task(ti=ti)
251
+
239
252
  def end(self) -> None:
240
253
  """End local and kubernetes executor."""
241
254
  self.local_executor.end()
@@ -28,8 +28,9 @@ def get_provider_info():
28
28
  "name": "Kubernetes",
29
29
  "description": "`Kubernetes <https://kubernetes.io/>`__\n",
30
30
  "state": "ready",
31
- "source-date-epoch": 1730012271,
31
+ "source-date-epoch": 1732429220,
32
32
  "versions": [
33
+ "10.0.1",
33
34
  "10.0.0",
34
35
  "9.0.1",
35
36
  "9.0.0",
@@ -20,9 +20,10 @@ import asyncio
20
20
  import contextlib
21
21
  import json
22
22
  import tempfile
23
+ from collections.abc import Generator
23
24
  from functools import cached_property
24
25
  from time import sleep
25
- from typing import TYPE_CHECKING, Any, Generator
26
+ from typing import TYPE_CHECKING, Any
26
27
 
27
28
  import aiofiles
28
29
  import tenacity
@@ -27,6 +27,7 @@ from kubernetes.client.rest import ApiException
27
27
  from slugify import slugify
28
28
 
29
29
  from airflow.configuration import conf
30
+ from airflow.providers.cncf.kubernetes.backcompat import get_logical_date_key
30
31
 
31
32
  if TYPE_CHECKING:
32
33
  from airflow.models.taskinstancekey import TaskInstanceKey
@@ -106,8 +107,10 @@ def annotations_to_key(annotations: dict[str, str]) -> TaskInstanceKey:
106
107
  from airflow.models.taskinstance import TaskInstance, TaskInstanceKey
107
108
  from airflow.settings import Session
108
109
 
109
- if not annotation_run_id and "execution_date" in annotations:
110
- execution_date = pendulum.parse(annotations["execution_date"])
110
+ logical_date_key = get_logical_date_key()
111
+
112
+ if not annotation_run_id and logical_date_key in annotations:
113
+ logical_date = pendulum.parse(annotations[logical_date_key])
111
114
  # Do _not_ use create-session, we don't want to expunge
112
115
  session = Session()
113
116
 
@@ -117,7 +120,7 @@ def annotations_to_key(annotations: dict[str, str]) -> TaskInstanceKey:
117
120
  .filter(
118
121
  TaskInstance.dag_id == dag_id,
119
122
  TaskInstance.task_id == task_id,
120
- DagRun.execution_date == execution_date,
123
+ getattr(DagRun, logical_date_key) == logical_date,
121
124
  )
122
125
  .scalar()
123
126
  )
@@ -22,8 +22,9 @@ import copy
22
22
  import json
23
23
  import logging
24
24
  import os
25
+ from collections.abc import Sequence
25
26
  from functools import cached_property
26
- from typing import TYPE_CHECKING, Sequence
27
+ from typing import TYPE_CHECKING
27
28
 
28
29
  from kubernetes.client import BatchV1Api, models as k8s
29
30
  from kubernetes.client.api_client import ApiClient
@@ -273,7 +274,6 @@ class KubernetesJobOperator(KubernetesPodOperator):
273
274
  kwargs = {
274
275
  "name": job.metadata.name,
275
276
  "namespace": job.metadata.namespace,
276
- "job": self.hook.batch_v1_client.api_client.sanitize_for_serialization(self.job),
277
277
  }
278
278
  if self.termination_grace_period is not None:
279
279
  kwargs.update(grace_period_seconds=self.termination_grace_period)
@@ -26,11 +26,11 @@ import os
26
26
  import re
27
27
  import shlex
28
28
  import string
29
- from collections.abc import Container, Mapping
29
+ from collections.abc import Container, Iterable, Mapping, Sequence
30
30
  from contextlib import AbstractContextManager
31
31
  from enum import Enum
32
32
  from functools import cached_property
33
- from typing import TYPE_CHECKING, Any, Callable, Iterable, Literal, Sequence
33
+ from typing import TYPE_CHECKING, Any, Callable, Literal
34
34
 
35
35
  import kubernetes
36
36
  import tenacity
@@ -19,8 +19,9 @@
19
19
  from __future__ import annotations
20
20
 
21
21
  import os
22
+ from collections.abc import Sequence
22
23
  from functools import cached_property
23
- from typing import TYPE_CHECKING, Sequence
24
+ from typing import TYPE_CHECKING
24
25
 
25
26
  import tenacity
26
27
  import yaml
@@ -198,8 +198,6 @@ class SparkKubernetesOperator(KubernetesPodOperator):
198
198
  "task_id": ti.task_id,
199
199
  "run_id": run_id,
200
200
  "spark_kubernetes_operator": "True",
201
- # 'execution_date': context['ts'],
202
- # 'try_number': context['ti'].try_number,
203
201
  }
204
202
 
205
203
  # If running on Airflow 2.3+:
@@ -41,6 +41,7 @@ from airflow.exceptions import (
41
41
  AirflowConfigException,
42
42
  AirflowException,
43
43
  )
44
+ from airflow.providers.cncf.kubernetes.backcompat import get_logical_date_key
44
45
  from airflow.providers.cncf.kubernetes.kubernetes_helper_functions import (
45
46
  POD_NAME_MAX_LENGTH,
46
47
  add_unique_suffix,
@@ -329,7 +330,7 @@ class PodGenerator:
329
330
  if map_index >= 0:
330
331
  annotations["map_index"] = str(map_index)
331
332
  if date:
332
- annotations["execution_date"] = date.isoformat()
333
+ annotations[get_logical_date_key()] = date.isoformat()
333
334
  if run_id:
334
335
  annotations["run_id"] = run_id
335
336
 
@@ -344,7 +345,7 @@ class PodGenerator:
344
345
  try_number=try_number,
345
346
  airflow_worker=scheduler_job_id,
346
347
  map_index=map_index,
347
- execution_date=date,
348
+ logical_date=date,
348
349
  run_id=run_id,
349
350
  ),
350
351
  ),
@@ -387,7 +388,7 @@ class PodGenerator:
387
388
  task_id,
388
389
  try_number,
389
390
  map_index=None,
390
- execution_date=None,
391
+ logical_date=None,
391
392
  run_id=None,
392
393
  airflow_worker=None,
393
394
  include_version=False,
@@ -402,7 +403,7 @@ class PodGenerator:
402
403
  task_id=task_id,
403
404
  try_number=try_number,
404
405
  map_index=map_index,
405
- execution_date=execution_date,
406
+ logical_date=logical_date,
406
407
  run_id=run_id,
407
408
  airflow_worker=airflow_worker,
408
409
  include_version=include_version,
@@ -422,7 +423,7 @@ class PodGenerator:
422
423
  try_number,
423
424
  airflow_worker=None,
424
425
  map_index=None,
425
- execution_date=None,
426
+ logical_date=None,
426
427
  run_id=None,
427
428
  include_version=True,
428
429
  ):
@@ -443,8 +444,8 @@ class PodGenerator:
443
444
  labels["airflow-worker"] = make_safe_label_value(str(airflow_worker))
444
445
  if map_index is not None and map_index >= 0:
445
446
  labels["map_index"] = str(map_index)
446
- if execution_date:
447
- labels["execution_date"] = datetime_to_label_safe_datestring(execution_date)
447
+ if logical_date:
448
+ labels[get_logical_date_key()] = datetime_to_label_safe_datestring(logical_date)
448
449
  if run_id:
449
450
  labels["run_id"] = make_safe_label_value(run_id)
450
451
  return labels
@@ -17,8 +17,9 @@
17
17
  # under the License.
18
18
  from __future__ import annotations
19
19
 
20
+ from collections.abc import Sequence
20
21
  from functools import cached_property
21
- from typing import TYPE_CHECKING, Sequence
22
+ from typing import TYPE_CHECKING
22
23
 
23
24
  from kubernetes import client
24
25
 
@@ -17,8 +17,9 @@
17
17
  from __future__ import annotations
18
18
 
19
19
  import asyncio
20
+ from collections.abc import AsyncIterator
20
21
  from functools import cached_property
21
- from typing import TYPE_CHECKING, Any, AsyncIterator
22
+ from typing import TYPE_CHECKING, Any
22
23
 
23
24
  from airflow.providers.cncf.kubernetes.hooks.kubernetes import AsyncKubernetesHook, KubernetesHook
24
25
  from airflow.providers.cncf.kubernetes.utils.pod_manager import PodManager
@@ -19,9 +19,10 @@ from __future__ import annotations
19
19
  import asyncio
20
20
  import datetime
21
21
  import traceback
22
+ from collections.abc import AsyncIterator
22
23
  from enum import Enum
23
24
  from functools import cached_property
24
- from typing import TYPE_CHECKING, Any, AsyncIterator
25
+ from typing import TYPE_CHECKING, Any
25
26
 
26
27
  from airflow.providers.cncf.kubernetes.hooks.kubernetes import AsyncKubernetesHook
27
28
  from airflow.providers.cncf.kubernetes.utils.pod_manager import (
@@ -16,7 +16,8 @@
16
16
  # under the License.
17
17
  from __future__ import annotations
18
18
 
19
- from typing import Callable, Iterator
19
+ from collections.abc import Iterator
20
+ from typing import Callable
20
21
 
21
22
  from kubernetes.utils import FailToCreateError
22
23
 
@@ -22,11 +22,11 @@ import enum
22
22
  import json
23
23
  import math
24
24
  import time
25
- from collections.abc import Iterable
25
+ from collections.abc import Generator, Iterable
26
26
  from contextlib import closing, suppress
27
27
  from dataclasses import dataclass
28
28
  from datetime import timedelta
29
- from typing import TYPE_CHECKING, Generator, Protocol, cast
29
+ from typing import TYPE_CHECKING, Protocol, cast
30
30
 
31
31
  import pendulum
32
32
  import tenacity
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: apache-airflow-providers-cncf-kubernetes
3
- Version: 10.0.0
3
+ Version: 10.0.1
4
4
  Summary: Provider package apache-airflow-providers-cncf-kubernetes for Apache Airflow
5
5
  Keywords: airflow-provider,cncf.kubernetes,airflow,integration
6
6
  Author-email: Apache Software Foundation <dev@airflow.apache.org>
@@ -28,8 +28,8 @@ Requires-Dist: google-re2>=1.0
28
28
  Requires-Dist: kubernetes>=29.0.0,<=31.0.0
29
29
  Requires-Dist: kubernetes_asyncio>=29.0.0,<=31.0.0
30
30
  Project-URL: Bug Tracker, https://github.com/apache/airflow/issues
31
- Project-URL: Changelog, https://airflow.apache.org/docs/apache-airflow-providers-cncf-kubernetes/10.0.0/changelog.html
32
- Project-URL: Documentation, https://airflow.apache.org/docs/apache-airflow-providers-cncf-kubernetes/10.0.0
31
+ Project-URL: Changelog, https://airflow.apache.org/docs/apache-airflow-providers-cncf-kubernetes/10.0.1/changelog.html
32
+ Project-URL: Documentation, https://airflow.apache.org/docs/apache-airflow-providers-cncf-kubernetes/10.0.1
33
33
  Project-URL: Slack Chat, https://s.apache.org/airflow-slack
34
34
  Project-URL: Source Code, https://github.com/apache/airflow
35
35
  Project-URL: Twitter, https://twitter.com/ApacheAirflow
@@ -79,7 +79,7 @@ Project-URL: YouTube, https://www.youtube.com/channel/UCSXwxpWZQ7XZ1WL3wqevChA/
79
79
 
80
80
  Package ``apache-airflow-providers-cncf-kubernetes``
81
81
 
82
- Release: ``10.0.0``
82
+ Release: ``10.0.1``
83
83
 
84
84
 
85
85
  `Kubernetes <https://kubernetes.io/>`__
@@ -92,7 +92,7 @@ This is a provider package for ``cncf.kubernetes`` provider. All classes for thi
92
92
  are in ``airflow.providers.cncf.kubernetes`` python package.
93
93
 
94
94
  You can find package information and changelog for the provider
95
- in the `documentation <https://airflow.apache.org/docs/apache-airflow-providers-cncf-kubernetes/10.0.0/>`_.
95
+ in the `documentation <https://airflow.apache.org/docs/apache-airflow-providers-cncf-kubernetes/10.0.1/>`_.
96
96
 
97
97
  Installation
98
98
  ------------
@@ -119,4 +119,4 @@ PIP package Version required
119
119
  ====================== =====================
120
120
 
121
121
  The changelog for the provider package can be found in the
122
- `changelog <https://airflow.apache.org/docs/apache-airflow-providers-cncf-kubernetes/10.0.0/changelog.html>`_.
122
+ `changelog <https://airflow.apache.org/docs/apache-airflow-providers-cncf-kubernetes/10.0.1/changelog.html>`_.
@@ -1,38 +1,38 @@
1
1
  airflow/providers/cncf/kubernetes/LICENSE,sha256=FFb4jd2AXnOOf7XLP04pQW6jbdhG49TxlGY6fFpCV1Y,13609
2
- airflow/providers/cncf/kubernetes/__init__.py,sha256=nxLYWteyTzCKa1NCHauBZsE1vOl0TSVqpqd4IR6taqg,1503
2
+ airflow/providers/cncf/kubernetes/__init__.py,sha256=WSfPJeVCftXHYzTgnGbSLoI5aWLsAVG5tXsBoOY9wSg,1503
3
3
  airflow/providers/cncf/kubernetes/callbacks.py,sha256=SK_gKvGWuU-nxHfsqsYMlNQ8HZbHfpvyItOqieel2lc,4162
4
- airflow/providers/cncf/kubernetes/get_provider_info.py,sha256=UdYm7n5XGH9N6hcCKJr5hMC5ekk-2lNP5wgj0plC5JY,18008
4
+ airflow/providers/cncf/kubernetes/get_provider_info.py,sha256=EtOtYPHX8N8LfiWkdJpTO2P4QdMSZDO2luESnyiWMUk,18030
5
5
  airflow/providers/cncf/kubernetes/k8s_model.py,sha256=xmdFhX29DjegoZ-cq8-KDL9soVYXf4OpU6fAGr3cPTU,2101
6
6
  airflow/providers/cncf/kubernetes/kube_client.py,sha256=yflZxLousXA9d7t67KrEy55qzb1cUhEyy6yCPkEem28,5329
7
7
  airflow/providers/cncf/kubernetes/kube_config.py,sha256=FAmhZZ_Z2JtoVzL6wENSjcwrlwAenHttTX_Ild9aEms,5225
8
- airflow/providers/cncf/kubernetes/kubernetes_helper_functions.py,sha256=tb6HykGOUKZIXXZssJyQLKBlWv_KoE5mjjxwOkeJHW0,5391
9
- airflow/providers/cncf/kubernetes/pod_generator.py,sha256=9Yd4FY0MbXc61JuOZwQu5WlFV6MlLBy72YMHF3lD8ao,19765
8
+ airflow/providers/cncf/kubernetes/kubernetes_helper_functions.py,sha256=Zf7RyNt9BkUHY7Sjm_6CimTmb2H1bv5lrO3T0pni_r0,5524
9
+ airflow/providers/cncf/kubernetes/pod_generator.py,sha256=KGFqR8IIo41-Z5sFtxBFOrc2cvL7s-ER8OVBhp2dFs0,19841
10
10
  airflow/providers/cncf/kubernetes/pod_generator_deprecated.py,sha256=aukRdia0Wtv0FVZXgvaIWQxdWfnT9cxzH0UwOVph8dE,11998
11
11
  airflow/providers/cncf/kubernetes/python_kubernetes_script.jinja2,sha256=I0EHRGwLHjSiX85e51HBIoddRDnC8TJPFrDBqQq_NJg,1776
12
12
  airflow/providers/cncf/kubernetes/python_kubernetes_script.py,sha256=KnTlZSWCZhwvj89fSc2kgIRTaI4iLNKPquHc2wXnluo,3460
13
13
  airflow/providers/cncf/kubernetes/secret.py,sha256=wj-T9gouqau_X14slAstGmnSxqXJQzdLwUdURzHna0I,5209
14
14
  airflow/providers/cncf/kubernetes/template_rendering.py,sha256=AZesc6MDfpFHoN1PvQpVwM-PzwbKYC1IsdChYvTubZ8,2965
15
- airflow/providers/cncf/kubernetes/backcompat/__init__.py,sha256=9hdXHABrVpkbpjZgUft39kOFL2xSGeG4GEua0Hmelus,785
15
+ airflow/providers/cncf/kubernetes/backcompat/__init__.py,sha256=KXF76f3v1jIFUBNz8kwxVMvm7i4mNo35LbIG9IijBNc,1299
16
16
  airflow/providers/cncf/kubernetes/backcompat/backwards_compat_converters.py,sha256=2jIehZsixt4ZGwTkj7kC8Uq3w8XwFAEzZV4g8SyIUZI,4340
17
17
  airflow/providers/cncf/kubernetes/cli/__init__.py,sha256=9hdXHABrVpkbpjZgUft39kOFL2xSGeG4GEua0Hmelus,785
18
- airflow/providers/cncf/kubernetes/cli/kubernetes_command.py,sha256=W49hsWZ3XWUJgFLte56tMNGqmOvcFitl7iFjmFR8Ezo,6990
18
+ airflow/providers/cncf/kubernetes/cli/kubernetes_command.py,sha256=wkI2gW2VfS_Ru1zX-Tr5ymLRP20ghAjdkD8RBtbUvt0,7384
19
19
  airflow/providers/cncf/kubernetes/decorators/__init__.py,sha256=mlJxuZLkd5x-iq2SBwD3mvRQpt3YR7wjz_nceyF1IaI,787
20
- airflow/providers/cncf/kubernetes/decorators/kubernetes.py,sha256=zVDHw_zwgRbobTOouJtCEqDrjrVwINGcB1dA-wG-ME0,5787
20
+ airflow/providers/cncf/kubernetes/decorators/kubernetes.py,sha256=-YgRnFGyS-tdoAqwKP_Jj5mh_YJlKpk5TvwYnphvp4o,5814
21
21
  airflow/providers/cncf/kubernetes/executors/__init__.py,sha256=mlJxuZLkd5x-iq2SBwD3mvRQpt3YR7wjz_nceyF1IaI,787
22
- airflow/providers/cncf/kubernetes/executors/kubernetes_executor.py,sha256=mVNIA5SSJj3hRWJy05Rp6DVhzNgrxW-pyENeIAv9Jdg,34271
23
- airflow/providers/cncf/kubernetes/executors/kubernetes_executor_types.py,sha256=9rRhfRuujGtSE73Ax0kC12whZCgWF2m6j5w9G9e0F_I,1673
24
- airflow/providers/cncf/kubernetes/executors/kubernetes_executor_utils.py,sha256=f2FHTyQyfFR1jjQmZV9bfX7U4Vxk5h61KPJO0yMcGbM,23356
25
- airflow/providers/cncf/kubernetes/executors/local_kubernetes_executor.py,sha256=6cEGS83tGVUm6tSsjVenaJXSstViBnwgrvu-XIW4XQg,10976
22
+ airflow/providers/cncf/kubernetes/executors/kubernetes_executor.py,sha256=2WPy9JCKVv9KinR0PZc1Sa8EXhjQMzArIxCms-H_EXE,35065
23
+ airflow/providers/cncf/kubernetes/executors/kubernetes_executor_types.py,sha256=L8_8HOHd_4O8WW6xT2tp49-yOj0EMKCYK5YqMOOx_bI,1973
24
+ airflow/providers/cncf/kubernetes/executors/kubernetes_executor_utils.py,sha256=lNdHp7Q5aTOxHBew-_H3cl9F4NLgmElNidhWXO3UKGw,24302
25
+ airflow/providers/cncf/kubernetes/executors/local_kubernetes_executor.py,sha256=kx6pHAfSnKiDgT6iDOS4fJRq49DodFnyxUyd-iJsuI8,11512
26
26
  airflow/providers/cncf/kubernetes/hooks/__init__.py,sha256=9hdXHABrVpkbpjZgUft39kOFL2xSGeG4GEua0Hmelus,785
27
- airflow/providers/cncf/kubernetes/hooks/kubernetes.py,sha256=WSWQZrAzyrjN9y5TCS796X1L7oB-Sq_2BUzhT9xAE2k,33632
27
+ airflow/providers/cncf/kubernetes/hooks/kubernetes.py,sha256=SIdFhIA1Et4asGMNbX96ZaRLPlAxDhM3l5liD_eJuH4,33659
28
28
  airflow/providers/cncf/kubernetes/kubernetes_executor_templates/__init__.py,sha256=9hdXHABrVpkbpjZgUft39kOFL2xSGeG4GEua0Hmelus,785
29
29
  airflow/providers/cncf/kubernetes/kubernetes_executor_templates/basic_template.yaml,sha256=yzJmXN4ZyB4aDwI_GIugpL9-f1YMVy__X-LQSbeU95A,2567
30
30
  airflow/providers/cncf/kubernetes/operators/__init__.py,sha256=mlJxuZLkd5x-iq2SBwD3mvRQpt3YR7wjz_nceyF1IaI,787
31
31
  airflow/providers/cncf/kubernetes/operators/custom_object_launcher.py,sha256=ZEXw_PqGItO47AEgGKqAqwFHFo-gb9-7jgEMRJgOfNU,15311
32
- airflow/providers/cncf/kubernetes/operators/job.py,sha256=RyPuT0yP7-tRrrS7uqDUBGI_xA9_YEg-JLUDJ5QcTA8,23809
33
- airflow/providers/cncf/kubernetes/operators/pod.py,sha256=f8JoEsgZbjSNlClTfw8XeCm-_vSkwpUglXzOiDyhBUg,53495
34
- airflow/providers/cncf/kubernetes/operators/resource.py,sha256=ccbZQKB1B5N4Y-ruItacB5Q105Tc0uNSoEmUAaSCrGQ,7570
35
- airflow/providers/cncf/kubernetes/operators/spark_kubernetes.py,sha256=rsUfqJ_TqjqZSIeUvc6J7pTJiaiX1Ba2WI5Tn9qtfbw,13923
32
+ airflow/providers/cncf/kubernetes/operators/job.py,sha256=mWstFYBzET1Pm7RYJyBOSZgjG_tb1s__DmWjb2An9jY,23738
33
+ airflow/providers/cncf/kubernetes/operators/pod.py,sha256=X_6OLr0BkaffKSTUGhGpC7yvuxvFIpaXZLGW7A2-I7k,53495
34
+ airflow/providers/cncf/kubernetes/operators/resource.py,sha256=4nS-eiVEGlotp-gCkHlwRuenj3pnKhZ4khh9s2cjZms,7597
35
+ airflow/providers/cncf/kubernetes/operators/spark_kubernetes.py,sha256=QQbJ9MwIHkTCnHwu2BLkJdTeYjhmla-7zY0zGwXhTpk,13822
36
36
  airflow/providers/cncf/kubernetes/pod_template_file_examples/__init__.py,sha256=9hdXHABrVpkbpjZgUft39kOFL2xSGeG4GEua0Hmelus,785
37
37
  airflow/providers/cncf/kubernetes/pod_template_file_examples/dags_in_image_template.yaml,sha256=7JdppZ-XDBpv2Bnde2SthhcME8w3b8xQdPAK1fJGW60,2256
38
38
  airflow/providers/cncf/kubernetes/pod_template_file_examples/dags_in_volume_template.yaml,sha256=-Pk_EwKpyWRYZKOnumUxVrDeAfFJ0nr3WZ7JNnvppzg,2442
@@ -42,16 +42,16 @@ airflow/providers/cncf/kubernetes/resource_convert/configmap.py,sha256=gf7DdVeD0
42
42
  airflow/providers/cncf/kubernetes/resource_convert/env_variable.py,sha256=CsVgLPXjI5pSDCBwcN3WCyyWPbiNRZc_OJCPK_C_298,1464
43
43
  airflow/providers/cncf/kubernetes/resource_convert/secret.py,sha256=ElZCMbTWeTKoPeIJ1fTvlqRXM8nGkWj2MrIlVckX6Ag,1494
44
44
  airflow/providers/cncf/kubernetes/sensors/__init__.py,sha256=9hdXHABrVpkbpjZgUft39kOFL2xSGeG4GEua0Hmelus,785
45
- airflow/providers/cncf/kubernetes/sensors/spark_kubernetes.py,sha256=ogD8m8baqPN_hGEXjN1NGp1dvslG8ZPBjy_LPr6Zo7I,5353
45
+ airflow/providers/cncf/kubernetes/sensors/spark_kubernetes.py,sha256=q5VZPf037pbsunFUjUrtz7M5oJW7waZ1q8snNAugCIk,5380
46
46
  airflow/providers/cncf/kubernetes/triggers/__init__.py,sha256=9hdXHABrVpkbpjZgUft39kOFL2xSGeG4GEua0Hmelus,785
47
- airflow/providers/cncf/kubernetes/triggers/job.py,sha256=fe0kaQos_m_1rVE-1YJBZKKFVLxrlHOB8oI5ntVzSN8,6727
48
- airflow/providers/cncf/kubernetes/triggers/pod.py,sha256=Q-1GPILDgGJHoxtkaH78edhNeR6BekRG8f0qpFLGcSI,12626
47
+ airflow/providers/cncf/kubernetes/triggers/job.py,sha256=DGbC1FZktBF-00Lb0pU9iIKQnmdW8HWklp5Wwq54OEY,6754
48
+ airflow/providers/cncf/kubernetes/triggers/pod.py,sha256=7vLj9SvOOwh9p5XSZIr7mj47YWe_aPQgtN7uEZhma68,12653
49
49
  airflow/providers/cncf/kubernetes/utils/__init__.py,sha256=ClZN0VPjWySdVwS_ktH7rrgL9VLAcs3OSJSB9s3zaYw,863
50
50
  airflow/providers/cncf/kubernetes/utils/delete_from.py,sha256=poObZSoEJwQyaYWilEURs8f4CDY2sn_pfwS31Lf579A,5195
51
- airflow/providers/cncf/kubernetes/utils/k8s_resource_iterator.py,sha256=-Pgc5i2WEDl7ZBvtJZ4eWDqqlSj8WdULqwUyOWmsRp8,1928
52
- airflow/providers/cncf/kubernetes/utils/pod_manager.py,sha256=Xp_K8nay4WYKbG_cJ9mrhc_sFkdmu40Klq859sq9vNs,33286
51
+ airflow/providers/cncf/kubernetes/utils/k8s_resource_iterator.py,sha256=DLypjkD_3YDixRTcsxEjgvHZNbbG9qamlz05eBqaWzU,1955
52
+ airflow/providers/cncf/kubernetes/utils/pod_manager.py,sha256=LmXsFO7CYP8YTZla4poN30UtayLyGdVkqicSPZh6hIA,33286
53
53
  airflow/providers/cncf/kubernetes/utils/xcom_sidecar.py,sha256=k6bdmVJ21OrAwGmWwledRrAmaty9ZrmbuM-IbaI4mqo,2519
54
- apache_airflow_providers_cncf_kubernetes-10.0.0.dist-info/entry_points.txt,sha256=ByD3QJJyP9CfmTYtpNI1953akD38RUDgpGXLaq9vpOw,111
55
- apache_airflow_providers_cncf_kubernetes-10.0.0.dist-info/WHEEL,sha256=CpUCUxeHQbRN5UGRQHYRJorO5Af-Qy_fHMctcQ8DSGI,82
56
- apache_airflow_providers_cncf_kubernetes-10.0.0.dist-info/METADATA,sha256=GQI7La3mlDH3aGgNxvWhkZSNNkJs4jEBkGLozAKa1WM,5212
57
- apache_airflow_providers_cncf_kubernetes-10.0.0.dist-info/RECORD,,
54
+ apache_airflow_providers_cncf_kubernetes-10.0.1.dist-info/entry_points.txt,sha256=ByD3QJJyP9CfmTYtpNI1953akD38RUDgpGXLaq9vpOw,111
55
+ apache_airflow_providers_cncf_kubernetes-10.0.1.dist-info/WHEEL,sha256=CpUCUxeHQbRN5UGRQHYRJorO5Af-Qy_fHMctcQ8DSGI,82
56
+ apache_airflow_providers_cncf_kubernetes-10.0.1.dist-info/METADATA,sha256=6S8NTSFwzZJyiT7KbJ7i19Km66J9uFo464oGGC7Id18,5212
57
+ apache_airflow_providers_cncf_kubernetes-10.0.1.dist-info/RECORD,,