Class: Krane::Pod

Inherits:
KubernetesResource show all
Defined in:
lib/krane/kubernetes_resource/pod.rb

Defined Under Namespace

Classes: Container

Constant Summary collapse

TIMEOUT =
10.minutes
FAILED_PHASE_NAME =
"Failed"
TRANSIENT_FAILURE_REASONS =
%w(
  Evicted
  Preempting
)

Constants inherited from KubernetesResource

KubernetesResource::ALLOWED_DEPLOY_METHOD_OVERRIDES, KubernetesResource::DEBUG_RESOURCE_NOT_FOUND_MESSAGE, KubernetesResource::DEPLOY_METHOD_OVERRIDE_ANNOTATION, KubernetesResource::DISABLED_EVENT_INFO_MESSAGE, KubernetesResource::DISABLED_LOG_INFO_MESSAGE, KubernetesResource::DISABLE_FETCHING_EVENT_INFO, KubernetesResource::DISABLE_FETCHING_LOG_INFO, KubernetesResource::GLOBAL, KubernetesResource::LAST_APPLIED_ANNOTATION, KubernetesResource::LOG_LINE_COUNT, KubernetesResource::SENSITIVE_TEMPLATE_CONTENT, KubernetesResource::SERVER_DRY_RUNNABLE, KubernetesResource::SERVER_DRY_RUN_DISABLED_ERROR, KubernetesResource::STANDARD_TIMEOUT_MESSAGE, KubernetesResource::SYNC_DEPENDENCIES, KubernetesResource::TIMEOUT_OVERRIDE_ANNOTATION, KubernetesResource::UNUSUAL_FAILURE_MESSAGE

Instance Attribute Summary collapse

Attributes inherited from KubernetesResource

#context, #deploy_started_at, #global, #name, #namespace, #type

Instance Method Summary collapse

Methods inherited from KubernetesResource

#<=>, build, class_for_kind, #current_generation, #debug_message, #deploy_method, #deploy_method_override, #deploy_started?, #deploy_timed_out?, #disappeared?, #exists?, #fetch_events, #file_path, #global?, #group, #id, kind, #kubectl_resource_type, #observed_generation, #pretty_status, #pretty_timeout_type, #report_status_to_statsd, #selected?, #sensitive_template_content?, #server_dry_run_validated?, #server_dry_runnable_resource?, #sync_debug_info, #terminating?, timeout, #timeout, #timeout_override, #to_kubeclient_resource, #use_generated_name, #uses_generate_name?, #validate_definition, #validation_error_msg, #validation_failed?, #version

Constructor Details

#initialize(namespace:, context:, definition:, logger:, statsd_tags: nil, parent: nil, deploy_started_at: nil, stream_logs: false) ⇒ Pod

Returns a new instance of Pod.



14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
# File 'lib/krane/kubernetes_resource/pod.rb', line 14

def initialize(namespace:, context:, definition:, logger:,
  statsd_tags: nil, parent: nil, deploy_started_at: nil, stream_logs: false)
  @parent = parent
  @deploy_started_at = deploy_started_at

  @containers = definition.fetch("spec", {}).fetch("containers", []).map { |c| Container.new(c) }
  unless @containers.present?
    logger.summary.add_paragraph("Rendered template content:\n#{definition.to_yaml}")
    raise FatalDeploymentError, "Template is missing required field spec.containers"
  end
  @containers += definition["spec"].fetch("initContainers", []).map { |c| Container.new(c, init_container: true) }
  @stream_logs = stream_logs
  super(namespace: namespace, context: context, definition: definition,
        logger: logger, statsd_tags: statsd_tags)
end

Instance Attribute Details

#stream_logsObject

Returns the value of attribute stream_logs.



12
13
14
# File 'lib/krane/kubernetes_resource/pod.rb', line 12

def stream_logs
  @stream_logs
end

Instance Method Details

#after_syncObject



42
43
44
45
46
47
48
# File 'lib/krane/kubernetes_resource/pod.rb', line 42

def after_sync
  if @stream_logs
    logs.print_latest
  elsif unmanaged? && deploy_succeeded?
    logs.print_all
  end
end

#deploy_failed?Boolean

Returns:

  • (Boolean)


63
64
65
# File 'lib/krane/kubernetes_resource/pod.rb', line 63

def deploy_failed?
  failure_message.present?
end

#deploy_succeeded?Boolean

Returns:

  • (Boolean)


55
56
57
58
59
60
61
# File 'lib/krane/kubernetes_resource/pod.rb', line 55

def deploy_succeeded?
  if unmanaged?
    phase == "Succeeded"
  else
    phase == "Running" && ready?
  end
end

#failure_messageObject



79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
# File 'lib/krane/kubernetes_resource/pod.rb', line 79

def failure_message
  doomed_containers = @containers.select(&:doomed?)
  if doomed_containers.present?
    container_problems = if unmanaged?
      "The following containers encountered errors:\n"
    else
      "The following containers are in a state that is unlikely to be recoverable:\n"
    end
    doomed_containers.each do |c|
      red_name = ColorizedString.new(c.name).red
      container_problems += "> #{red_name}: #{c.doom_reason}\n"
    end
  end
  "#{phase_failure_message} #{container_problems}".strip.presence
end

#fetch_debug_logsObject



95
96
97
98
# File 'lib/krane/kubernetes_resource/pod.rb', line 95

def fetch_debug_logs
  logs.sync
  logs
end

#node_nameObject



104
105
106
# File 'lib/krane/kubernetes_resource/pod.rb', line 104

def node_name
  @instance_data.dig('spec', 'nodeName')
end

Returns:

  • (Boolean)


100
101
102
# File 'lib/krane/kubernetes_resource/pod.rb', line 100

def print_debug_logs?
  exists? && !@stream_logs # don't print them a second time
end

#statusObject



50
51
52
53
# File 'lib/krane/kubernetes_resource/pod.rb', line 50

def status
  return phase if reason.blank?
  "#{phase} (Reason: #{reason})"
end

#sync(_cache) ⇒ Object



30
31
32
33
34
35
36
37
38
39
40
# File 'lib/krane/kubernetes_resource/pod.rb', line 30

def sync(_cache)
  super
  raise_predates_deploy_error if exists? && unmanaged? && !deploy_started?

  if exists?
    logs.sync if unmanaged?
    update_container_statuses(@instance_data["status"])
  else # reset
    @containers.each(&:reset_status)
  end
end

#timeout_messageObject



67
68
69
70
71
72
73
74
75
76
77
# File 'lib/krane/kubernetes_resource/pod.rb', line 67

def timeout_message
  if readiness_probe_failure?
    probe_failure_msgs = @containers.map(&:readiness_fail_reason).compact
    header = "The following containers have not passed their readiness probes on at least one pod:\n"
    header + probe_failure_msgs.join("\n")
  elsif failed_schedule_reason.present?
    "Pod could not be scheduled because #{failed_schedule_reason}"
  else
    STANDARD_TIMEOUT_MESSAGE
  end
end