|
1 | 1 | """Provides support for launching and managing kernels within a Kubernetes cluster."""
|
2 |
| - |
| 2 | +import os |
| 3 | +from datetime import datetime |
| 4 | +from kubernetes import config |
| 5 | +from kubernetes.config.config_exception import ConfigException |
3 | 6 | from remote_kernel_provider import RemoteKernelProviderBase
|
4 | 7 |
|
5 | 8 |
|
| 9 | +LOGGED_WARNING_INTERVAL = int(os.getenv("K8SKP_LOGGED_WARNING_INTERVAL_SECS", "600")) # log no more than every 10 min |
| 10 | +last_logged_warning = datetime.min |
| 11 | +first_time = True |
| 12 | +in_cluster = False |
| 13 | + |
| 14 | + |
6 | 15 | class KubernetesKernelProvider(RemoteKernelProviderBase):
|
7 | 16 | id = 'k8skp'
|
8 | 17 | kernel_file = 'k8skp_kernel.json'
|
9 | 18 | lifecycle_manager_classes = ['kubernetes_kernel_provider.k8s.KubernetesKernelLifecycleManager']
|
| 19 | + |
| 20 | + def find_kernels(self): |
| 21 | + """ Ensures the provider is running within a Kubernetes cluster. If not, it will |
| 22 | + log a warning message and no kernelspecs will be returned. Since find_kernels() |
| 23 | + is frequently called, it will only log the warning periodically (10 minutes by default). |
| 24 | + """ |
| 25 | + global first_time, in_cluster, last_logged_warning |
| 26 | + |
| 27 | + # Only check the cluster config once since the results can't change unless restarted. |
| 28 | + if first_time: |
| 29 | + try: |
| 30 | + config.load_incluster_config() |
| 31 | + in_cluster = True |
| 32 | + except ConfigException as ce: |
| 33 | + # Check to see if we're in-cluster via env. If in-cluster, periodically |
| 34 | + # log a warning |
| 35 | + if os.getenv('KUBERNETES_SERVICE_HOST') is not None: |
| 36 | + raise ce # Got an exception in-cluster - let it be known |
| 37 | + first_time = False |
| 38 | + |
| 39 | + if not in_cluster: |
| 40 | + current_time = datetime.now() |
| 41 | + delta = current_time - last_logged_warning |
| 42 | + if delta.days > 0 or delta.seconds > LOGGED_WARNING_INTERVAL: |
| 43 | + self.log.warning("KubernetesKernelProvider must be run from within a Kubernetes " |
| 44 | + "cluster. No Kubernetes kernels will be available.") |
| 45 | + last_logged_warning = current_time |
| 46 | + return {} |
| 47 | + |
| 48 | + return super(KubernetesKernelProvider, self).find_kernels() |
0 commit comments