class Krane::DaemonSet
def deploy_failed?
def deploy_failed? pods.present? && pods.any?(&:deploy_failed?) && observed_generation == current_generation end
def deploy_succeeded?
def deploy_succeeded? return false unless exists? current_generation == observed_generation && rollout_data["desiredNumberScheduled"].to_i == rollout_data["updatedNumberScheduled"].to_i && relevant_pods_ready? end
def fetch_debug_logs
def fetch_debug_logs most_useful_pod = pods.find(&:deploy_failed?) || pods.find(&:deploy_timed_out?) || pods.first most_useful_pod.fetch_debug_logs end
def find_nodes(cache)
def find_nodes(cache) all_nodes = cache.get_all(Node.kind) all_nodes.each_with_object([]) do |node_data, relevant_nodes| next if node_data.dig('spec', 'unschedulable').to_s.downcase == 'true' cond = node_data.dig('status', 'conditions').find { |c| c['type'].downcase == 'ready' } next if (!cond.nil? && cond['status'].downcase != 'true') relevant_nodes << Node.new(definition: node_data) end end
def parent_of_pod?(pod_data)
def parent_of_pod?(pod_data) return false unless pod_data.dig("metadata", "ownerReferences") template_generation = @instance_data.dig("spec", "templateGeneration") || @instance_data.dig("metadata", "annotations", "deprecated.daemonset.template.generation") return false unless template_generation.present? pod_data["metadata"]["ownerReferences"].any? { |ref| ref["uid"] == @instance_data["metadata"]["uid"] } && pod_data["metadata"]["labels"]["pod-template-generation"].to_i == template_generation.to_i end
def print_debug_logs?
def print_debug_logs? pods.present? # the kubectl command times out if no pods exist end
def refresh_nodes(cache)
def refresh_nodes(cache) new_nodes = find_nodes(cache) return new_nodes if @nodes.blank? # Remove non-existent nodes @nodes.select do |node| new_nodes.find { |n| n.name == node.name } != nil end end
def relevant_pods_ready?
def relevant_pods_ready? return true if rollout_data["desiredNumberScheduled"].to_i == rollout_data["numberReady"].to_i # all pods ready relevant_node_names = @nodes.map(&:name) considered_pods = @pods.select { |p| relevant_node_names.include?(p.node_name) && !p.evicted? } @logger.debug("DaemonSet is reporting #{rollout_data['numberReady']} pods ready." \ " Considered #{considered_pods.size} pods out of #{@pods.size} for #{@nodes.size} nodes.") considered_pods.present? && considered_pods.all?(&:deploy_succeeded?) && rollout_data["numberReady"].to_i >= considered_pods.length end
def rollout_data
def rollout_data return { "currentNumberScheduled" => 0 } unless exists? @instance_data["status"] .slice("updatedNumberScheduled", "desiredNumberScheduled", "numberReady") end
def status
def status return super unless exists? rollout_data.map { |state_replicas, num| "#{num} #{state_replicas}" }.join(", ") end
def sync(cache)
def sync(cache) super @pods = exists? ? find_pods(cache) : [] @nodes = refresh_nodes(cache) end