def _do_compute_node(gs, input_queue, cluster_guid, node, g): assert isinstance(gs, global_state.GlobalState) assert isinstance(input_queue, Queue.PriorityQueue) assert utilities.valid_string(cluster_guid) assert utilities.is_wrapped_object(node, 'Node') assert isinstance(g, ContextGraph) node_id = node['id'] node_guid = 'Node:' + node_id g.add_resource(node_guid, node['annotations'], 'Node', node['timestamp'], node['properties']) g.add_relation(cluster_guid, node_guid, 'contains') # Cluster contains Node # Pods in a Node pod_ids = set() docker_hosts = set() # Process pods sequentially because calls to _do_compute_pod() do not call # lower-level services or wait. for pod in kubernetes.get_pods(gs, node_id): _do_compute_pod(gs, cluster_guid, node_guid, pod, g) pod_ids.add(pod['id']) # pod.properties.spec.nodeName may be missing if the pod is waiting. docker_host = utilities.get_attribute( pod, ['properties', 'spec', 'nodeName']) if utilities.valid_string(docker_host): docker_hosts.add(docker_host) # 'docker_hosts' should contain a single Docker host, because all of # the pods run in the same Node. However, if it is not the case, we # cannot fix the situation, so we just log an error message and continue. if len(docker_hosts) != 1: gs.logger_error( 'corrupt pod data in node=%s: ' '"docker_hosts" is empty or contains more than one entry: %s', node_guid, str(docker_hosts)) # Process containers concurrently. for docker_host in docker_hosts: for container in docker.get_containers_with_metrics(gs, docker_host): parent_pod_id = utilities.get_parent_pod_id(container) if utilities.valid_string(parent_pod_id) and (parent_pod_id in pod_ids): # This container is contained in a pod. parent_guid = 'Pod:' + parent_pod_id else: # This container is not contained in a pod. parent_guid = node_guid # Do not compute the containers by worker threads in test mode # because the order of the output will be different than the golden # files due to the effects of queuing the work. if gs.get_testing(): _do_compute_container(gs, docker_host, parent_guid, container, g) else: input_queue.put(( gs.get_random_priority(), _do_compute_container, {'gs': gs, 'docker_host': docker_host, 'parent_guid': parent_guid, 'container': container, 'g': g}))
def _do_compute_pod(gs, input_queue, node_guid, pod, g): assert isinstance(gs, global_state.GlobalState) assert isinstance(input_queue, Queue.PriorityQueue) assert utilities.valid_string(node_guid) assert utilities.is_wrapped_object(pod, 'Pod') assert isinstance(g, ContextGraph) pod_id = pod['id'] pod_guid = 'Pod:' + pod_id docker_host = utilities.get_attribute(pod, ['properties', 'spec', 'host']) if not utilities.valid_string(docker_host): msg = ('Docker host (pod.properties.spec.host) ' 'not found in pod ID %s' % pod_id) gs.logger_error(msg) raise collector_error.CollectorError(msg) g.add_resource(pod_guid, pod['annotations'], 'Pod', pod['timestamp'], pod['properties']) g.add_relation(node_guid, pod_guid, 'runs') # Node runs Pod # Containers in a Pod for container in docker.get_containers_with_metrics(gs, docker_host): if not _container_in_pod(gs, container, pod): continue # Do not compute the containers by worker threads in test mode because the # order of the output will be different than the golden files due to the # effects of queuing the work. if gs.get_testing(): _do_compute_container(gs, docker_host, pod_guid, container, g) else: input_queue.put((gs.get_random_priority(), _do_compute_container, { 'gs': gs, 'docker_host': docker_host, 'pod_guid': pod_guid, 'container': container, 'g': g }))
def get_containers(): """Computes the response of the '/cluster/resources/containers' endpoint. Returns: The containers of the context graph. """ containers = [] gs = app.context_graph_global_state try: for node in kubernetes.get_nodes(gs): # The node_id is the Docker host name. docker_host = node['id'] containers.extend(docker.get_containers_with_metrics(gs, docker_host)) except collector_error.CollectorError as e: return flask.jsonify(utilities.make_error(str(e))) except: msg = 'get_containers() failed with exception %s' % sys.exc_info()[0] app.logger.exception(msg) return flask.jsonify(utilities.make_error(msg)) return flask.jsonify(utilities.make_response(containers, 'resources'))
def _do_compute_pod(gs, input_queue, node_guid, pod, g): assert isinstance(gs, global_state.GlobalState) assert isinstance(input_queue, Queue.PriorityQueue) assert utilities.valid_string(node_guid) assert utilities.is_wrapped_object(pod, 'Pod') assert isinstance(g, ContextGraph) pod_id = pod['id'] pod_guid = 'Pod:' + pod_id docker_host = utilities.get_attribute( pod, ['properties', 'spec', 'host']) if not utilities.valid_string(docker_host): msg = ('Docker host (pod.properties.spec.host) ' 'not found in pod ID %s' % pod_id) gs.logger_error(msg) raise collector_error.CollectorError(msg) g.add_resource(pod_guid, pod['annotations'], 'Pod', pod['timestamp'], pod['properties']) g.add_relation(node_guid, pod_guid, 'runs') # Node runs Pod # Containers in a Pod for container in docker.get_containers_with_metrics(gs, docker_host): if not _container_in_pod(gs, container, pod): continue # Do not compute the containers by worker threads in test mode because the # order of the output will be different than the golden files due to the # effects of queuing the work. if gs.get_testing(): _do_compute_container(gs, docker_host, pod_guid, container, g) else: input_queue.put(( gs.get_random_priority(), _do_compute_container, {'gs': gs, 'docker_host': docker_host, 'pod_guid': pod_guid, 'container': container, 'g': g}))
def get_containers(): """Computes the response of the '/cluster/resources/containers' endpoint. Returns: The containers of the context graph. """ containers = [] gs = app.context_graph_global_state try: for node in kubernetes.get_nodes(gs): # The node_id is the Docker host name. docker_host = node['id'] containers.extend( docker.get_containers_with_metrics(gs, docker_host)) except collector_error.CollectorError as e: return flask.jsonify(utilities.make_error(str(e))) except: msg = 'get_containers() failed with exception %s' % sys.exc_info()[0] app.logger.exception(msg) return flask.jsonify(utilities.make_error(msg)) return flask.jsonify(utilities.make_response(containers, 'resources'))