From 875131982064fb898bc695fd2fa4456a3d402cd8 Mon Sep 17 00:00:00 2001 From: Marat Sharafutdinov Date: Wed, 7 Aug 2019 14:27:54 +0300 Subject: [PATCH] Add wait_sleep parameter for the k8s module (#59714) (#59854) --- changelogs/fragments/k8s_wait_sleep.yml | 2 ++ lib/ansible/module_utils/k8s/raw.py | 20 ++++++++++--------- lib/ansible/modules/clustering/k8s/k8s.py | 5 +++++ test/integration/targets/k8s/tasks/waiter.yml | 6 ++++++ 4 files changed, 24 insertions(+), 9 deletions(-) create mode 100644 changelogs/fragments/k8s_wait_sleep.yml diff --git a/changelogs/fragments/k8s_wait_sleep.yml b/changelogs/fragments/k8s_wait_sleep.yml new file mode 100644 index 00000000000..51a256074f6 --- /dev/null +++ b/changelogs/fragments/k8s_wait_sleep.yml @@ -0,0 +1,2 @@ +minor_changes: + - k8s - add `wait_sleep` parameter (number of seconds to sleep between checks). diff --git a/lib/ansible/module_utils/k8s/raw.py b/lib/ansible/module_utils/k8s/raw.py index 02a2ebf835b..7a6d889ddcc 100644 --- a/lib/ansible/module_utils/k8s/raw.py +++ b/lib/ansible/module_utils/k8s/raw.py @@ -78,6 +78,7 @@ class KubernetesRawModule(KubernetesAnsibleModule): argument_spec.update(copy.deepcopy(AUTH_ARG_SPEC)) argument_spec['merge_type'] = dict(type='list', choices=['json', 'merge', 'strategic-merge']) argument_spec['wait'] = dict(type='bool', default=False) + argument_spec['wait_sleep'] = dict(type='int', default=5) argument_spec['wait_timeout'] = dict(type='int', default=120) argument_spec['wait_condition'] = dict(type='dict', default=None, options=self.condition_spec) argument_spec['validate'] = dict(type='dict', default=None, options=self.validate_spec) @@ -226,6 +227,7 @@ class KubernetesRawModule(KubernetesAnsibleModule): namespace = definition['metadata'].get('namespace') existing = None wait = self.params.get('wait') + wait_sleep = self.params.get('wait_sleep') wait_timeout = self.params.get('wait_timeout') wait_condition = None if self.params.get('wait_condition') and self.params['wait_condition'].get('type'): @@ -274,7 +276,7 @@ class KubernetesRawModule(KubernetesAnsibleModule): self.fail_json(msg="Failed to delete object: {0}".format(exc.body), error=exc.status, status=exc.status, reason=exc.reason) if wait: - success, resource, duration = self.wait(resource, definition, wait_timeout, 'absent') + success, resource, duration = self.wait(resource, definition, wait_sleep, wait_timeout, 'absent') result['duration'] = duration if not success: self.fail_json(msg="Resource deletion timed out", **result) @@ -294,7 +296,7 @@ class KubernetesRawModule(KubernetesAnsibleModule): success = True result['result'] = k8s_obj if wait: - success, result['result'], result['duration'] = self.wait(resource, definition, wait_timeout) + success, result['result'], result['duration'] = self.wait(resource, definition, wait_sleep, wait_timeout) if existing: existing = existing.to_dict() else: @@ -328,7 +330,7 @@ class KubernetesRawModule(KubernetesAnsibleModule): success = True result['result'] = k8s_obj if wait and not self.check_mode: - success, result['result'], result['duration'] = self.wait(resource, definition, wait_timeout, condition=wait_condition) + success, result['result'], result['duration'] = self.wait(resource, definition, wait_sleep, wait_timeout, condition=wait_condition) result['changed'] = True result['method'] = 'create' if not success: @@ -353,7 +355,7 @@ class KubernetesRawModule(KubernetesAnsibleModule): success = True result['result'] = k8s_obj if wait: - success, result['result'], result['duration'] = self.wait(resource, definition, wait_timeout, condition=wait_condition) + success, result['result'], result['duration'] = self.wait(resource, definition, wait_sleep, wait_timeout, condition=wait_condition) match, diffs = self.diff_objects(existing.to_dict(), result['result']) result['changed'] = not match result['method'] = 'replace' @@ -381,7 +383,7 @@ class KubernetesRawModule(KubernetesAnsibleModule): success = True result['result'] = k8s_obj if wait: - success, result['result'], result['duration'] = self.wait(resource, definition, wait_timeout, condition=wait_condition) + success, result['result'], result['duration'] = self.wait(resource, definition, wait_sleep, wait_timeout, condition=wait_condition) match, diffs = self.diff_objects(existing.to_dict(), result['result']) result['changed'] = not match result['method'] = 'patch' @@ -422,7 +424,7 @@ class KubernetesRawModule(KubernetesAnsibleModule): result['method'] = 'create' return result - def _wait_for(self, resource, name, namespace, predicate, timeout, state): + def _wait_for(self, resource, name, namespace, predicate, sleep, timeout, state): start = datetime.now() def _wait_for_elapsed(): @@ -437,7 +439,7 @@ class KubernetesRawModule(KubernetesAnsibleModule): return True, response.to_dict(), _wait_for_elapsed() else: return True, {}, _wait_for_elapsed() - time.sleep(timeout // 20) + time.sleep(sleep) except NotFoundError: if state == 'absent': return True, {}, _wait_for_elapsed() @@ -445,7 +447,7 @@ class KubernetesRawModule(KubernetesAnsibleModule): response = response.to_dict() return False, response, _wait_for_elapsed() - def wait(self, resource, definition, timeout, state='present', condition=None): + def wait(self, resource, definition, sleep, timeout, state='present', condition=None): def _deployment_ready(deployment): # FIXME: frustratingly bool(deployment.status) is True even if status is empty @@ -500,4 +502,4 @@ class KubernetesRawModule(KubernetesAnsibleModule): predicate = _custom_condition else: predicate = _resource_absent - return self._wait_for(resource, definition['metadata']['name'], definition['metadata'].get('namespace'), predicate, timeout, state) + return self._wait_for(resource, definition['metadata']['name'], definition['metadata'].get('namespace'), predicate, sleep, timeout, state) diff --git a/lib/ansible/modules/clustering/k8s/k8s.py b/lib/ansible/modules/clustering/k8s/k8s.py index 076a2282976..9008af767f1 100644 --- a/lib/ansible/modules/clustering/k8s/k8s.py +++ b/lib/ansible/modules/clustering/k8s/k8s.py @@ -76,6 +76,11 @@ options: default: no type: bool version_added: "2.8" + wait_sleep: + description: + - Number of seconds to sleep between checks. + default: 5 + version_added: "2.9" wait_timeout: description: - How long in seconds to wait for the resource to end up in the desired state. Ignored if C(wait) is not set. diff --git a/test/integration/targets/k8s/tasks/waiter.yml b/test/integration/targets/k8s/tasks/waiter.yml index cc0c1c78afc..757d7899aca 100644 --- a/test/integration/targets/k8s/tasks/waiter.yml +++ b/test/integration/targets/k8s/tasks/waiter.yml @@ -53,6 +53,7 @@ app: "{{ k8s_pod_name }}" template: "{{ k8s_pod_template }}" wait: yes + wait_sleep: 3 wait_timeout: 180 vars: k8s_pod_name: wait-ds @@ -80,6 +81,7 @@ type: RollingUpdate template: "{{ k8s_pod_template }}" wait: yes + wait_sleep: 3 wait_timeout: 180 vars: k8s_pod_name: wait-ds @@ -107,6 +109,7 @@ type: RollingUpdate template: "{{ k8s_pod_template }}" wait: yes + wait_sleep: 3 wait_timeout: 180 vars: k8s_pod_name: wait-ds @@ -138,6 +141,7 @@ namespace: "{{ wait_namespace }}" spec: "{{ k8s_pod_spec }}" wait: yes + wait_sleep: 1 wait_timeout: 30 vars: k8s_pod_name: wait-crash-pod @@ -162,6 +166,7 @@ namespace: "{{ wait_namespace }}" spec: "{{ k8s_pod_spec }}" wait: yes + wait_sleep: 1 wait_timeout: 30 vars: k8s_pod_name: wait-no-image-pod @@ -330,6 +335,7 @@ namespace: "{{ wait_namespace }}" state: absent wait: yes + wait_sleep: 2 wait_timeout: 5 ignore_errors: yes register: short_wait_remove_pod