-
Notifications
You must be signed in to change notification settings - Fork 115
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Rework deploy output #98
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,87 @@ | ||
module KubernetesDeploy | ||
# Adds the methods kubernetes-deploy requires to your logger class. | ||
# These methods include helpers for logging consistent headings, as well as facilities for | ||
# displaying key information later, in a summary section, rather than when it occurred. | ||
module DeferredSummaryLogging | ||
attr_reader :summary | ||
def initialize(*args) | ||
reset | ||
super | ||
end | ||
|
||
def reset | ||
@summary = DeferredSummary.new | ||
@current_phase = 0 | ||
end | ||
|
||
def blank_line(level = :info) | ||
public_send(level, "") | ||
end | ||
|
||
def phase_heading(phase_name) | ||
@current_phase += 1 | ||
heading("Phase #{@current_phase}: #{phase_name}") | ||
end | ||
|
||
def heading(text, secondary_msg = '', secondary_msg_color = :blue) | ||
padding = (100.0 - (text.length + secondary_msg.length)) / 2 | ||
blank_line | ||
part1 = ColorizedString.new("#{'-' * padding.floor}#{text}").blue | ||
part2 = ColorizedString.new(secondary_msg).colorize(secondary_msg_color) | ||
part3 = ColorizedString.new('-' * padding.ceil).blue | ||
info(part1 + part2 + part3) | ||
end | ||
|
||
# Outputs the deferred summary information saved via @logger.summary.add_action and @logger.summary.add_paragraph | ||
def print_summary(success) | ||
if success | ||
heading("Result: ", "SUCCESS", :green) | ||
level = :info | ||
else | ||
heading("Result: ", "FAILURE", :red) | ||
level = :fatal | ||
end | ||
|
||
public_send(level, summary.actions_sentence) | ||
summary.paragraphs.each do |para| | ||
blank_line(level) | ||
msg_lines = para.split("\n") | ||
msg_lines.each { |line| public_send(level, line) } | ||
end | ||
end | ||
|
||
class DeferredSummary | ||
attr_reader :paragraphs | ||
|
||
def initialize | ||
@actions_taken = [] | ||
@paragraphs = [] | ||
end | ||
|
||
def actions_sentence | ||
case @actions_taken.length | ||
when 0 then "No actions taken" | ||
else | ||
@actions_taken.to_sentence.capitalize | ||
end | ||
end | ||
|
||
# Saves a sentence fragment to be displayed in the first sentence of the summary section | ||
# | ||
# Example: | ||
# # The resulting summary will begin with "Created 3 secrets and failed to deploy 2 resources" | ||
# @logger.summary.add_action("created 3 secrets") | ||
# @logger.summary.add_cation("failed to deploy 2 resources") | ||
def add_action(sentence_fragment) | ||
@actions_taken << sentence_fragment | ||
end | ||
|
||
# Adds a paragraph to be displayed in the summary section | ||
# Paragraphs will be printed in the order they were added, separated by a blank line | ||
# This can be used to log a block of data on a particular topic, e.g. debug info for a particular failed resource | ||
def add_paragraph(paragraph) | ||
paragraphs << paragraph | ||
end | ||
end | ||
end | ||
end |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -8,12 +8,13 @@ def sync | |
@found = st.success? | ||
@rollout_data = {} | ||
@status = nil | ||
@representative_pod = nil | ||
@pods = [] | ||
|
||
if @found | ||
@rollout_data = JSON.parse(json_data)["status"] | ||
.slice("updatedReplicas", "replicas", "availableReplicas", "unavailableReplicas") | ||
@status, _err, _ = kubectl.run("rollout", "status", type, @name, "--watch=false") if @deploy_started | ||
@status = @rollout_data.map { |replica_state, num| "#{num} #{replica_state}" }.join(", ") | ||
|
||
pod_list, _err, st = kubectl.run("get", "pods", "-a", "-l", "name=#{name}", "--output=json") | ||
if st.success? | ||
|
@@ -30,12 +31,24 @@ def sync | |
) | ||
pod.deploy_started = @deploy_started | ||
pod.interpret_json_data(pod_json) | ||
|
||
if !@representative_pod && pod_probably_new?(pod_json) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This makes me 😢 / 😳 , but it lets us provide the huge benefit of pod logs/events on deployment failures without waiting for much bigger (200+ LOC) changes required to do this properly. That code is already mostly written here so ideally the hack will be in the wild for a very short time. I think this is worth doing to get the output changes in front of users sooner. Risks:
|
||
@representative_pod = pod | ||
end | ||
@pods << pod | ||
end | ||
end | ||
end | ||
end | ||
|
||
log_status | ||
def fetch_logs | ||
@representative_pod ? @representative_pod.fetch_logs : {} | ||
end | ||
|
||
def fetch_events | ||
own_events = super | ||
return own_events unless @representative_pod | ||
own_events.merge(@representative_pod.fetch_events) | ||
end | ||
|
||
def deploy_succeeded? | ||
|
@@ -59,8 +72,12 @@ def exists? | |
@found | ||
end | ||
|
||
def status_data | ||
super.merge(replicas: @rollout_data, num_pods: @pods.length) | ||
private | ||
|
||
def pod_probably_new?(pod_json) | ||
return false unless @deploy_started | ||
# Shitty, brittle workaround to identify a pod from the new ReplicaSet before implementing ReplicaSet awareness | ||
Time.parse(pod_json["metadata"]["creationTimestamp"]) >= (@deploy_started - 30.seconds) | ||
end | ||
end | ||
end |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These changes aren't strictly related to this PR. I just noticed that these resources were effectively re-syncing every time we called
deploy_succeeded?