kubernetes-deploy 0.9.3 → 0.9.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +7 -4
- data/lib/kubernetes-deploy/kubernetes_resource/pod.rb +14 -0
- data/lib/kubernetes-deploy/runner.rb +29 -31
- data/lib/kubernetes-deploy/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 861c1898e40c08f1120bc55896920e0359f3f674
|
4
|
+
data.tar.gz: 6c34e454e654acfba418245f3b2a2896272885cb
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4fc044006b4330a42b2d7b60e4b45c67b5be86ffd1c2e4017be9042f21d38a9d695058413ce78a9112406b0c8abf8e3c15bcf04f331f7ccf196cdcff6e62b387
|
7
|
+
data.tar.gz: 61e7d6cd0d6c706fb1db1a601708f781005db36b3e932e8c22a18463580c4b8c551bfdac2db2df0b0ebef1b75258e2e1ae81044595cf7345c4fced52c4f97b6c
|
data/README.md
CHANGED
@@ -257,6 +257,8 @@ To install this gem onto your local machine, run `bundle exec rake install`.
|
|
257
257
|
|
258
258
|
To see the full-color output of a specific integration test, you can use `PRINT_LOGS=1 bundle exec ruby -I test test/integration/kubernetes_deploy_test.rb -n/test_name/`.
|
259
259
|
|
260
|
+
To make StatsD log what it would have emitted, run a test with `STATSD_DEV=1`.
|
261
|
+
|
260
262
|
|
261
263
|
|
262
264
|
![test-output](screenshots/test-output.png)
|
@@ -265,11 +267,12 @@ To see the full-color output of a specific integration test, you can use `PRINT_
|
|
265
267
|
|
266
268
|
## Releasing a new version (Shopify employees)
|
267
269
|
|
268
|
-
1. Update the version number in `version.rb` and commit that change
|
269
|
-
2. Tag the version with `git tag vx.y.z
|
270
|
-
3.
|
270
|
+
1. Update the version number in `version.rb` and commit that change with message "Version x.y.z". Don't push yet or you'll confuse Shipit.
|
271
|
+
2. Tag the version with `git tag vx.y.z -a -m "Version x.y.z"`
|
272
|
+
3. Push both your bump commit and its tag simultaneously with `git push origin master --follow-tags` (note that you can set `git config --global push.followTags true` to turn this flag on by default)
|
273
|
+
4. Use the [Shipit Stack](https://shipit.shopify.io/shopify/kubernetes-deploy/rubygems) to build the `.gem` file and upload to [rubygems.org](https://rubygems.org/gems/kubernetes-deploy).
|
271
274
|
|
272
|
-
If Shipit fails with `You need to create the v0.7.9 tag first
|
275
|
+
If you push your commit and the tag separately, Shipit usually fails with `You need to create the v0.7.9 tag first.`. To make it find your tag, go to `Settings` > `Resynchronize this stack` > `Clear git cache`.
|
273
276
|
|
274
277
|
|
275
278
|
|
@@ -19,6 +19,7 @@ module KubernetesDeploy
|
|
19
19
|
if pod_data.blank?
|
20
20
|
raw_json, _err, st = kubectl.run("get", type, @name, "-a", "--output=json")
|
21
21
|
pod_data = JSON.parse(raw_json) if st.success?
|
22
|
+
raise_predates_deploy_error if pod_data.present? && unmanaged? && !@deploy_started
|
22
23
|
end
|
23
24
|
|
24
25
|
if pod_data.present?
|
@@ -147,6 +148,19 @@ module KubernetesDeploy
|
|
147
148
|
@already_displayed = true
|
148
149
|
end
|
149
150
|
|
151
|
+
def raise_predates_deploy_error
|
152
|
+
example_color = :green
|
153
|
+
msg = <<-STRING.strip_heredoc
|
154
|
+
Unmanaged pods like #{id} must have unique names on every deploy in order to work as intended.
|
155
|
+
The recommended way to achieve this is to include "<%= deployment_id %>" in the pod's name, like this:
|
156
|
+
#{ColorizedString.new('kind: Pod').colorize(example_color)}
|
157
|
+
#{ColorizedString.new('metadata:').colorize(example_color)}
|
158
|
+
#{ColorizedString.new("name: #{@name}-<%= deployment_id %>").colorize(example_color)}
|
159
|
+
STRING
|
160
|
+
@logger.summary.add_paragraph(msg)
|
161
|
+
raise FatalDeploymentError, "#{id} existed before the deploy started"
|
162
|
+
end
|
163
|
+
|
150
164
|
class Container
|
151
165
|
STATUS_SCAFFOLD = {
|
152
166
|
"state" => {
|
@@ -187,16 +187,11 @@ module KubernetesDeploy
|
|
187
187
|
|
188
188
|
# Inspect the file referenced in the kubectl stderr
|
189
189
|
# to make it easier for developer to understand what's going on
|
190
|
-
def
|
191
|
-
#
|
192
|
-
# Error from server (
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
path = match[:path]
|
197
|
-
if path.present? && File.file?(path)
|
198
|
-
File.read(path)
|
199
|
-
end
|
190
|
+
def find_bad_files_from_kubectl_output(stderr)
|
191
|
+
# stderr often contains one or more lines like the following, from which we can extract the file path(s):
|
192
|
+
# Error from server (TypeOfError): error when creating "/path/to/service-gqq5oh.yml": Service "web" is invalid:
|
193
|
+
matches = stderr.scan(%r{"(/\S+\.ya?ml\S*)"})
|
194
|
+
matches.flatten if matches
|
200
195
|
end
|
201
196
|
|
202
197
|
def deploy_has_priority_resources?(resources)
|
@@ -239,17 +234,8 @@ module KubernetesDeploy
|
|
239
234
|
command = ["create", "-f", file_path, "--dry-run", "--output=name"]
|
240
235
|
_, err, st = kubectl.run(*command, log_failure: false)
|
241
236
|
return if st.success?
|
242
|
-
|
243
|
-
|
244
|
-
This usually means template '#{original_filename}' is not a valid Kubernetes template.
|
245
|
-
Error from kubectl:
|
246
|
-
#{err}
|
247
|
-
Rendered template content:
|
248
|
-
DEBUG_MSG
|
249
|
-
debug_msg += File.read(file_path)
|
250
|
-
@logger.summary.add_paragraph(debug_msg)
|
251
|
-
|
252
|
-
raise FatalDeploymentError, "Kubectl dry run failed (command: #{Shellwords.join(command)})"
|
237
|
+
record_invalid_template(err, file_paths: [file_path], original_filenames: [original_filename])
|
238
|
+
raise FatalDeploymentError, "Template validation failed (command: #{Shellwords.join(command)})"
|
253
239
|
end
|
254
240
|
|
255
241
|
def split_templates(filename)
|
@@ -270,20 +256,28 @@ module KubernetesDeploy
|
|
270
256
|
raise FatalDeploymentError, "Template '#{filename}' cannot be parsed"
|
271
257
|
end
|
272
258
|
|
273
|
-
def
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
|
259
|
+
def record_invalid_template(err, file_paths:, original_filenames: nil)
|
260
|
+
template_names = Array(original_filenames)
|
261
|
+
file_content = Array(file_paths).each_with_object([]) do |file_path, contents|
|
262
|
+
next unless File.file?(file_path)
|
263
|
+
contents << File.read(file_path)
|
264
|
+
template_names << File.basename(file_path) unless original_filenames
|
265
|
+
end.join("\n")
|
266
|
+
template_list = template_names.compact.join(", ").presence || "See error message"
|
267
|
+
|
268
|
+
debug_msg = ColorizedString.new("Invalid #{'template'.pluralize(template_names.length)}: #{template_list}\n").red
|
269
|
+
debug_msg += "> Error from kubectl:\n#{indent_four(err)}"
|
270
|
+
if file_content.present?
|
271
|
+
debug_msg += "\n> Rendered template content:\n#{indent_four(file_content)}"
|
282
272
|
end
|
283
273
|
|
284
274
|
@logger.summary.add_paragraph(debug_msg)
|
285
275
|
end
|
286
276
|
|
277
|
+
def indent_four(str)
|
278
|
+
" " + str.gsub("\n", "\n ")
|
279
|
+
end
|
280
|
+
|
287
281
|
def wait_for_completion(watched_resources, started_at)
|
288
282
|
watcher = ResourceWatcher.new(watched_resources, logger: @logger, deploy_started_at: started_at)
|
289
283
|
watcher.run
|
@@ -407,7 +401,11 @@ module KubernetesDeploy
|
|
407
401
|
if st.success?
|
408
402
|
log_pruning(out) if prune
|
409
403
|
else
|
410
|
-
|
404
|
+
file_paths = find_bad_files_from_kubectl_output(err)
|
405
|
+
warn_msg = "WARNING: Any resources not mentioned in the error below were likely created/updated. " \
|
406
|
+
"You may wish to roll back this deploy."
|
407
|
+
@logger.summary.add_paragraph(ColorizedString.new(warn_msg).yellow)
|
408
|
+
record_invalid_template(err, file_paths: file_paths)
|
411
409
|
raise FatalDeploymentError, "Command failed: #{Shellwords.join(command)}"
|
412
410
|
end
|
413
411
|
end
|