X-Git-Url: https://gerrit.onap.org/r/gitweb?a=blobdiff_plain;f=kubernetes%2Freadiness%2Fdocker%2Finit%2Fready.py;h=db7105a18d4850ce5ed4f360891756b8bb2ad148;hb=8f855a643979a8a13e079950ef15ac11d5f096ae;hp=f4a5e5da8fc3b852b7a5ab7f836c6c7c07a44e70;hpb=782351dfbd683f4a5f77e450369ac29d56922d68;p=oom.git diff --git a/kubernetes/readiness/docker/init/ready.py b/kubernetes/readiness/docker/init/ready.py index f4a5e5da8f..db7105a18d 100644 --- a/kubernetes/readiness/docker/init/ready.py +++ b/kubernetes/readiness/docker/init/ready.py @@ -1,9 +1,10 @@ -#!/usr/bin/python +#!/usr/bin/env python import getopt import logging import os import sys import time +import random from kubernetes import client @@ -19,7 +20,8 @@ with open(token_path, 'r') as token_file: # setup logging log = logging.getLogger(__name__) handler = logging.StreamHandler(sys.stdout) -handler.setFormatter(logging.Formatter('%(asctime)s - %(levelname)s - %(message)s')) +formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(message)s') +handler.setFormatter(formatter) handler.setLevel(logging.INFO) log.addHandler(handler) log.setLevel(logging.INFO) @@ -30,32 +32,89 @@ configuration.ssl_ca_cert = cert configuration.api_key['authorization'] = token configuration.api_key_prefix['authorization'] = 'Bearer' coreV1Api = client.CoreV1Api(client.ApiClient(configuration)) +api_instance = client.ExtensionsV1beta1Api(client.ApiClient(configuration)) +api = client.AppsV1beta1Api(client.ApiClient(configuration)) +batchV1Api = client.BatchV1Api(client.ApiClient(configuration)) + + +def is_job_complete(job_name): + complete = False + log.info("Checking if " + job_name + " is complete") + try: + response = batchV1Api.read_namespaced_job_status(job_name, namespace) + if response.status.succeeded == 1: + job_status_type = response.status.conditions[0].type + if job_status_type == "Complete": + complete = True + log.info(job_name + " is complete") + else: + log.info(job_name + " is not complete") + else: + log.info(job_name + " has not succeeded yet") + return complete + except Exception as e: + log.error("Exception when calling read_namespaced_job_status: %s\n" % e) + + +def wait_for_statefulset_complete(statefulset_name): + try: + response = api.read_namespaced_stateful_set(statefulset_name, namespace) + s = response.status + if (s.updated_replicas == response.spec.replicas and + s.replicas == response.spec.replicas and + s.ready_replicas == response.spec.replicas and + s.current_replicas == response.spec.replicas and + s.observed_generation == response.metadata.generation): + log.info("Statefulset " + statefulset_name + " is ready") + return True + else: + log.info("Statefulset " + statefulset_name + " is not ready") + return False + except Exception as e: + log.error("Exception when waiting for Statefulset status: %s\n" % e) + + +def wait_for_deployment_complete(deployment_name): + try: + response = api.read_namespaced_deployment(deployment_name, namespace) + s = response.status + if (s.unavailable_replicas is None and + s.updated_replicas == response.spec.replicas and + s.replicas == response.spec.replicas and + s.ready_replicas == response.spec.replicas and + s.observed_generation == response.metadata.generation): + log.info("Deployment " + deployment_name + " is ready") + return True + else: + log.info("Deployment " + deployment_name + " is not ready") + return False + except Exception as e: + log.error("Exception when waiting for deployment status: %s\n" % e) + def is_ready(container_name): ready = False log.info("Checking if " + container_name + " is ready") try: - response = coreV1Api.list_namespaced_pod(namespace=namespace, watch=False) + response = coreV1Api.list_namespaced_pod(namespace=namespace, + watch=False) for i in response.items: # container_statuses can be None, which is non-iterable. if i.status.container_statuses is None: continue for s in i.status.container_statuses: - if i.metadata.owner_references[0].kind == "StatefulSet": - if i.metadata.name == container_name: - ready = s.ready - if not ready: - log.info(container_name + " is not ready.") - else: - log.info(container_name + " is ready!") - else: - continue - elif s.name == container_name: - ready = s.ready - if not ready: - log.info(container_name + " is not ready.") - else: - log.info(container_name + " is ready!") + if s.name == container_name: + name = read_name(i) + if i.metadata.owner_references[0].kind == "StatefulSet": + ready = wait_for_statefulset_complete(name) + elif i.metadata.owner_references[0].kind == "ReplicaSet": + deployment_name = get_deployment_name(name) + ready = wait_for_deployment_complete(deployment_name) + elif i.metadata.owner_references[0].kind == "Job": + ready = is_job_complete(name) + + return ready + else: continue return ready @@ -63,19 +122,35 @@ def is_ready(container_name): log.error("Exception when calling list_namespaced_pod: %s\n" % e) +def read_name(item): + return item.metadata.owner_reference[0].name + + +def get_deployment_name(replicaset): + api_response = api_instance.read_namespaced_replica_set_status(replicaset, + namespace) + deployment_name = read_name(api_response) + return deployment_name + + DEF_TIMEOUT = 10 DESCRIPTION = "Kubernetes container readiness check utility" -USAGE = "Usage: ready.py [-t ] -c [-c ...]\n" \ +USAGE = "Usage: ready.py [-t ] -c " \ + "[-c ...]\n" \ "where\n" \ - " - wait for container readiness timeout in min, default is " + str(DEF_TIMEOUT) + "\n" \ + " - wait for container readiness timeout in min, " \ + "default is " + str(DEF_TIMEOUT) + "\n" \ " - name of the container to wait for\n" + def main(argv): # args are a list of container names container_names = [] timeout = DEF_TIMEOUT try: - opts, args = getopt.getopt(argv, "hc:t:", ["container-name=", "timeout=", "help"]) + opts, args = getopt.getopt(argv, "hc:t:", ["container-name=", + "timeout=", + "help"]) for opt, arg in opts: if opt in ("-h", "--help"): print("%s\n\n%s" % (DESCRIPTION, USAGE)) @@ -100,10 +175,13 @@ def main(argv): if ready is True: break elif time.time() > timeout: - log.warning("timed out waiting for '" + container_name + "' to be ready") + log.warning("timed out waiting for '" + container_name + + "' to be ready") exit(1) else: - time.sleep(5) + # spread in time potentially parallel execution in multiple + # containers + time.sleep(random.randint(5, 11)) if __name__ == "__main__":