kubernetes-deploy 0.7.4 → 0.7.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 255ea8b3ecd484e3867da8b34b4a61a927d99c1f
4
- data.tar.gz: 79c4034b3460995f65fbeb54216688a5b1f448b6
3
+ metadata.gz: 8974c6df435df28dab80164ebdea271275813e2b
4
+ data.tar.gz: a4d53b653bb5cfa44307f92f865bcdf08a5c1540
5
5
  SHA512:
6
- metadata.gz: 8c9b9c54dea86318add19d23123e00ec5f3195488ec0ecbf954cdfe126dd1ca780d2c7cea6687342f2df8410ef7c5a53fd8b3ebb0649b6e8488fb1f2be42f0ef
7
- data.tar.gz: a2cc7698a3b9f9b66bf8a54b7c5ac2483946760cdb52612c8b73fbc3c57ad8f716e8cedb4e1a732ecda59a82f37815de4ba41eb212a1e75399bd461b06061ebc
6
+ metadata.gz: 3f2d103ec8b209060c2bcfcb426ac7a7ed002770ac45f2e5ca1aed2d918e86dc6636509ce0eb26610702cf29689b57e48696e41d99a64c2d7ead4a4ac0169ac6
7
+ data.tar.gz: 2d7f6b144b8c8af3d577ec8fd4f1636b6e274510df9b32036b7f1e4865abc71b3a75eea03c7427a7c46cce9b63019b85bf3a2ce242b0673ea72e9cc6d7ae0b3e
@@ -154,25 +154,18 @@ module KubernetesDeploy
154
154
  # Returns a hash in the following format:
155
155
  # {
156
156
  # "pod/web-1" => [
157
- # {"subject_kind" => "Pod", "some" => "stuff"}, # event 1
158
- # {"subject_kind" => "Pod", "other" => "stuff"}, # event 2
157
+ # "Pulling: pulling image "hello-world:latest" (1 events)",
158
+ # "Pulled: Successfully pulled image "hello-world:latest" (1 events)"
159
159
  # ]
160
160
  # }
161
161
  def fetch_events
162
162
  return {} unless exists?
163
- fields = "{.involvedObject.kind}\t{.count}\t{.message}\t{.reason}"
164
- out, _err, st = kubectl.run("get", "events",
165
- %(--output=jsonpath={range .items[?(@.involvedObject.name=="#{name}")]}#{fields}\n{end}))
163
+ out, _err, st = kubectl.run("get", "events", "--output=go-template=#{Event.go_template_for(type, name)}")
166
164
  return {} unless st.success?
167
165
 
168
166
  event_collector = Hash.new { |hash, key| hash[key] = [] }
169
- out.split("\n").each_with_object(event_collector) do |event_blob, events|
170
- pieces = event_blob.split("\t")
171
- subject_kind = pieces[0]
172
- # jsonpath can only filter by one thing at a time, and we chose involvedObject.name
173
- # This means we still need to filter by involvedObject.kind here to make sure we only retain relevant events
174
- next unless subject_kind.downcase == type.downcase
175
- events[id] << "#{pieces[3] || 'Unknown'}: #{pieces[2]} (#{pieces[1]} events)" # Reason: Message (X events)
167
+ Event.extract_all_from_go_template_blob(out).each_with_object(event_collector) do |candidate, events|
168
+ events[id] << candidate.to_s if candidate.seen_since?(@deploy_started - 5.seconds)
176
169
  end
177
170
  end
178
171
 
@@ -192,5 +185,61 @@ module KubernetesDeploy
192
185
  def kubectl
193
186
  @kubectl ||= Kubectl.new(namespace: @namespace, context: @context, logger: @logger, log_failure_by_default: false)
194
187
  end
188
+
189
+ class Event
190
+ EVENT_SEPARATOR = "ENDEVENT--BEGINEVENT"
191
+ FIELD_SEPARATOR = "ENDFIELD--BEGINFIELD"
192
+ FIELDS = %w(
193
+ .involvedObject.kind
194
+ .involvedObject.name
195
+ .count
196
+ .lastTimestamp
197
+ .reason
198
+ .message
199
+ )
200
+
201
+ def self.go_template_for(kind, name)
202
+ and_conditions = [
203
+ %[(eq .involvedObject.kind "#{kind}")],
204
+ %[(eq .involvedObject.name "#{name}")],
205
+ '(ne .reason "Started")',
206
+ '(ne .reason "Created")'
207
+ ]
208
+ condition_start = "{{if and #{and_conditions.join(' ')}}}"
209
+ field_part = FIELDS.map { |f| "{{#{f}}}" }.join(%({{print "#{FIELD_SEPARATOR}"}}))
210
+ %({{range .items}}#{condition_start}#{field_part}{{print "#{EVENT_SEPARATOR}"}}{{end}}{{end}})
211
+ end
212
+
213
+ def self.extract_all_from_go_template_blob(blob)
214
+ blob.split(EVENT_SEPARATOR).map do |event_blob|
215
+ pieces = event_blob.split(FIELD_SEPARATOR, FIELDS.length)
216
+ new(
217
+ subject_kind: pieces[FIELDS.index(".involvedObject.kind")],
218
+ subject_name: pieces[FIELDS.index(".involvedObject.name")],
219
+ count: pieces[FIELDS.index(".count")],
220
+ last_timestamp: pieces[FIELDS.index(".lastTimestamp")],
221
+ reason: pieces[FIELDS.index(".reason")],
222
+ message: pieces[FIELDS.index(".message")]
223
+ )
224
+ end
225
+ end
226
+
227
+ def initialize(subject_kind:, last_timestamp:, reason:, message:, count:, subject_name:)
228
+ @subject_kind = subject_kind
229
+ @subject_name = subject_name
230
+ @last_timestamp = Time.parse(last_timestamp)
231
+ @reason = reason
232
+ @message = message.tr("\n", '')
233
+ @count = count.to_i
234
+ end
235
+
236
+ def seen_since?(time)
237
+ time.to_i <= @last_timestamp.to_i
238
+ end
239
+
240
+ def to_s
241
+ "#{@reason}: #{@message} (#{@count} events)"
242
+ end
243
+ end
195
244
  end
196
245
  end
@@ -12,38 +12,57 @@ module KubernetesDeploy
12
12
  @deploy_started_at = deploy_started_at
13
13
  end
14
14
 
15
- def run(delay_sync: 3.seconds)
16
- delay_sync_until = Time.now.utc
15
+ def run(delay_sync: 3.seconds, reminder_interval: 30.seconds)
16
+ delay_sync_until = last_message_logged_at = Time.now.utc
17
17
 
18
18
  while @resources.present?
19
19
  if Time.now.utc < delay_sync_until
20
20
  sleep(delay_sync_until - Time.now.utc)
21
21
  end
22
- watch_time = (Time.now.utc - @deploy_started_at).round(1)
23
22
  delay_sync_until = Time.now.utc + delay_sync # don't pummel the API if the sync is fast
23
+
24
24
  @resources.each(&:sync)
25
25
  newly_finished_resources, @resources = @resources.partition(&:deploy_finished?)
26
26
 
27
- new_success_list = []
28
- newly_finished_resources.each do |resource|
29
- if resource.deploy_failed?
30
- @logger.error("#{resource.id} failed to deploy after #{watch_time}s")
31
- elsif resource.deploy_timed_out?
32
- @logger.error("#{resource.id} deployment timed out")
33
- else
34
- new_success_list << resource.id
35
- end
27
+ if newly_finished_resources.present?
28
+ watch_time = (Time.now.utc - @deploy_started_at).round(1)
29
+ report_what_just_happened(newly_finished_resources, watch_time)
30
+ report_what_is_left(reminder: false)
31
+ last_message_logged_at = Time.now.utc
32
+ elsif due_for_reminder?(last_message_logged_at, reminder_interval)
33
+ report_what_is_left(reminder: true)
34
+ last_message_logged_at = Time.now.utc
36
35
  end
36
+ end
37
+ end
37
38
 
38
- unless new_success_list.empty?
39
- success_string = ColorizedString.new("Successfully deployed in #{watch_time}s:").green
40
- @logger.info("#{success_string} #{new_success_list.join(', ')}")
41
- end
39
+ private
42
40
 
43
- if newly_finished_resources.present? && @resources.present? # something happened this cycle, more to go
44
- @logger.info("Continuing to wait for: #{@resources.map(&:id).join(', ')}")
41
+ def report_what_just_happened(resources, watch_time)
42
+ new_successes, new_failures = resources.partition(&:deploy_succeeded?)
43
+ new_failures.each do |resource|
44
+ if resource.deploy_failed?
45
+ @logger.error("#{resource.id} failed to deploy after #{watch_time}s")
46
+ else
47
+ @logger.error("#{resource.id} deployment timed out")
45
48
  end
46
49
  end
50
+
51
+ if new_successes.present?
52
+ success_string = ColorizedString.new("Successfully deployed in #{watch_time}s:").green
53
+ @logger.info("#{success_string} #{new_successes.map(&:id).join(', ')}")
54
+ end
55
+ end
56
+
57
+ def report_what_is_left(reminder:)
58
+ return unless @resources.present?
59
+ resource_list = @resources.map(&:id).join(', ')
60
+ msg = reminder ? "Still waiting for: #{resource_list}" : "Continuing to wait for: #{resource_list}"
61
+ @logger.info(msg)
62
+ end
63
+
64
+ def due_for_reminder?(last_message_logged_at, reminder_interval)
65
+ (last_message_logged_at.to_f + reminder_interval.to_f) <= Time.now.utc.to_f
47
66
  end
48
67
  end
49
68
  end
@@ -1,3 +1,3 @@
1
1
  module KubernetesDeploy
2
- VERSION = "0.7.4"
2
+ VERSION = "0.7.5"
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: kubernetes-deploy
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.7.4
4
+ version: 0.7.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Katrina Verey
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: exe
11
11
  cert_chain: []
12
- date: 2017-06-05 00:00:00.000000000 Z
12
+ date: 2017-06-15 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: activesupport