Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
systemsmanagement:Uyuni:Master:CentOS6-Uyuni-Client-Tools
salt
fix-for-delete_deployment-in-kubernetes-module....
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File fix-for-delete_deployment-in-kubernetes-module.patch of Package salt
From 6f0fc27f5b99adfd9a2fa907e2e2aec01f6d611e Mon Sep 17 00:00:00 2001 From: Jochen Breuer <jbreuer@suse.de> Date: Wed, 23 Aug 2017 21:31:28 +0200 Subject: [PATCH] Fix for delete_deployment in Kubernetes module The Kubernetes module function delete_deployment() uses api_instance.delete_namespaced_deployment() from the Kubernetes lib. This method from the Kubernetes lib returns immediately without giving a success or failure indication, which lets Salt mark the job as failed even though we don't know if it failed or not. To actually get a result I've implemented a polling via show_deployment() to check if the deployment got removed. If a time limit is hit, we are returning with an error, otherwise it is a success. Since Windows has no signal.alarm implementation, we are here falling back to loop counting. --- salt/exceptions.py | 6 +++++ salt/modules/kubernetes.py | 44 ++++++++++++++++++++++++++++++++++- tests/unit/modules/test_kubernetes.py | 21 +++++++++-------- 3 files changed, 60 insertions(+), 11 deletions(-) diff --git a/salt/exceptions.py b/salt/exceptions.py index bd396aca89..84ab414cc2 100644 --- a/salt/exceptions.py +++ b/salt/exceptions.py @@ -261,6 +261,12 @@ class SaltCacheError(SaltException): ''' +class TimeoutError(SaltException): + ''' + Thrown when an opration cannot be completet within a given time limit. + ''' + + class SaltReqTimeoutError(SaltException): ''' Thrown when a salt master request call fails to return within the timeout diff --git a/salt/modules/kubernetes.py b/salt/modules/kubernetes.py index d3d02f2e26..8f2fd2f646 100644 --- a/salt/modules/kubernetes.py +++ b/salt/modules/kubernetes.py @@ -39,11 +39,15 @@ import base64 import logging import yaml import tempfile +import signal +from time import sleep +from contextlib import contextmanager from salt.exceptions import CommandExecutionError from salt.ext.six import iteritems import salt.utils import salt.utils.templates +from salt.ext.six.moves import range # pylint: disable=import-error try: import kubernetes # pylint: disable=import-self @@ -79,6 +83,21 @@ def __virtual__(): return False, 'python kubernetes library not found' +if not salt.utils.is_windows(): + @contextmanager + def _time_limit(seconds): + def signal_handler(signum, frame): + raise TimeoutException + signal.signal(signal.SIGALRM, signal_handler) + signal.alarm(seconds) + try: + yield + finally: + signal.alarm(0) + + POLLING_TIME_LIMIT = 30 + + # pylint: disable=no-member def _setup_conn(**kwargs): ''' @@ -693,7 +712,30 @@ def delete_deployment(name, namespace='default', **kwargs): name=name, namespace=namespace, body=body) - return api_response.to_dict() + mutable_api_response = api_response.to_dict() + if not salt.utils.is_windows(): + try: + with _time_limit(POLLING_TIME_LIMIT): + while show_deployment(name, namespace) is not None: + sleep(1) + else: # pylint: disable=useless-else-on-loop + mutable_api_response['code'] = 200 + except TimeoutException: + pass + else: + # Windows has not signal.alarm implementation, so we are just falling + # back to loop-counting. + for i in range(60): + if show_deployment(name, namespace) is None: + mutable_api_response['code'] = 200 + break + else: + sleep(1) + if mutable_api_response['code'] != 200: + log.warning('Reached polling time limit. Deployment is not yet ' + 'deleted, but we are backing off. Sorry, but you\'ll ' + 'have to check manually.') + return mutable_api_response except (ApiException, HTTPError) as exc: if isinstance(exc, ApiException) and exc.status == 404: return None diff --git a/tests/unit/modules/test_kubernetes.py b/tests/unit/modules/test_kubernetes.py index 3357cad2df..493822a93c 100644 --- a/tests/unit/modules/test_kubernetes.py +++ b/tests/unit/modules/test_kubernetes.py @@ -94,19 +94,20 @@ class KubernetesTestCase(TestCase): def test_delete_deployments(self): ''' - Tests deployment creation. + Tests deployment deletion :return: ''' with patch('salt.modules.kubernetes.kubernetes') as mock_kubernetes_lib: - with patch.dict(kubernetes.__salt__, {'config.option': Mock(return_value="")}): - mock_kubernetes_lib.client.V1DeleteOptions = Mock(return_value="") - mock_kubernetes_lib.client.ExtensionsV1beta1Api.return_value = Mock( - **{"delete_namespaced_deployment.return_value.to_dict.return_value": {}} - ) - self.assertEqual(kubernetes.delete_deployment("test"), {}) - self.assertTrue( - kubernetes.kubernetes.client.ExtensionsV1beta1Api(). - delete_namespaced_deployment().to_dict.called) + with patch('salt.modules.kubernetes.show_deployment', Mock(return_value=None)): + with patch.dict(kubernetes.__salt__, {'config.option': Mock(return_value="")}): + mock_kubernetes_lib.client.V1DeleteOptions = Mock(return_value="") + mock_kubernetes_lib.client.ExtensionsV1beta1Api.return_value = Mock( + **{"delete_namespaced_deployment.return_value.to_dict.return_value": {'code': ''}} + ) + self.assertEqual(kubernetes.delete_deployment("test"), {'code': 200}) + self.assertTrue( + kubernetes.kubernetes.client.ExtensionsV1beta1Api(). + delete_namespaced_deployment().to_dict.called) def test_create_deployments(self): ''' -- 2.13.6
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor