vidar 0.3.4 → 0.4.0
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 +4 -4
- data/.gitignore +1 -0
- data/Gemfile.lock +3 -1
- data/lib/vidar.rb +1 -1
- data/lib/vidar/cli.rb +21 -10
- data/lib/vidar/deploy_status.rb +17 -10
- data/lib/vidar/k8s/container_status.rb +28 -9
- data/lib/vidar/k8s/pod_set.rb +72 -0
- data/lib/vidar/log.rb +2 -2
- data/lib/vidar/version.rb +1 -1
- data/vidar.gemspec +1 -0
- metadata +17 -3
- data/lib/vidar/k8s/pods.rb +0 -56
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: fbf6458e4bf0f50913580e72f32a2b9fa20dff7d6775a4cf0f3af209f5c7b0a9
|
4
|
+
data.tar.gz: b4fdcdf35ca12932c6a867c18d9f769c58dcad5ad4cc899585cbb2322e0e3db1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: cd6382056fb7fca1864adf9110a7fea122f20b785ecd590219cbf62968a4ab1f88163955df3c1fd48e185620f429cb89a9b863ac6d82f6087566076d454b897e
|
7
|
+
data.tar.gz: e3a4ff265a97cc941282f20ebd37325530e2af079f432c16f207e295e7c14ea18ae62aeb93fb69ff74c4a5cbd4190b8bed2bd8c9ab8c89827415a73afb7b93e9
|
data/.gitignore
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
vidar (0.
|
4
|
+
vidar (0.4.0)
|
5
5
|
colorize
|
6
6
|
faraday
|
7
7
|
thor (~> 0.20)
|
@@ -10,6 +10,7 @@ GEM
|
|
10
10
|
remote: https://rubygems.org/
|
11
11
|
specs:
|
12
12
|
ast (2.4.0)
|
13
|
+
awesome_print (1.8.0)
|
13
14
|
coderay (1.1.2)
|
14
15
|
colorize (0.8.1)
|
15
16
|
diff-lcs (1.3)
|
@@ -56,6 +57,7 @@ PLATFORMS
|
|
56
57
|
ruby
|
57
58
|
|
58
59
|
DEPENDENCIES
|
60
|
+
awesome_print
|
59
61
|
bundler
|
60
62
|
pry
|
61
63
|
rake
|
data/lib/vidar.rb
CHANGED
data/lib/vidar/cli.rb
CHANGED
@@ -59,14 +59,11 @@ module Vidar
|
|
59
59
|
end
|
60
60
|
|
61
61
|
desc "deploy", "Performs k8s deployment with deploy hook"
|
62
|
-
method_option :revision,
|
62
|
+
method_option :revision, required: false
|
63
63
|
def deploy
|
64
64
|
revision = options[:revision] || Config.get!(:revision)
|
65
65
|
Log.info "Current cluster_name: #{Config.get!(:cluster_name)} ###"
|
66
66
|
|
67
|
-
Log.info "Set kubectl image..."
|
68
|
-
Run.kubectl "set image deployments,cronjobs *=#{Config.get!(:image)}:#{revision} --all"
|
69
|
-
|
70
67
|
Log.info "Looking for deploy hook..."
|
71
68
|
template_name, error, status = Open3.capture3 "kubectl get cronjob deploy-hook-template -n #{Config.get!(:namespace)} -o name --ignore-not-found=true"
|
72
69
|
|
@@ -76,12 +73,24 @@ module Vidar
|
|
76
73
|
else
|
77
74
|
Log.info "Executing deploy hook #{template_name.strip!}..."
|
78
75
|
Run.kubectl "delete job deploy-hook --ignore-not-found=true"
|
76
|
+
Run.kubectl "set image cronjobs deploy-hook-template=#{Config.get!(:image)}:#{revision} --all"
|
79
77
|
Run.kubectl "create job deploy-hook --from=#{template_name}"
|
78
|
+
|
79
|
+
deploy_status = Vidar::DeployStatus.new(namespace: Config.get!(:namespace), filter: "deploy-hook")
|
80
|
+
deploy_status.wait_until_completed
|
81
|
+
|
82
|
+
unless deploy_status.success?
|
83
|
+
Log.error "Error running deploy hook template"
|
84
|
+
exit(1)
|
85
|
+
end
|
80
86
|
end
|
81
87
|
else
|
82
88
|
Log.info "Error getting deploy hook template: #{error}"
|
83
89
|
exit(1)
|
84
90
|
end
|
91
|
+
|
92
|
+
Log.info "Set kubectl image..."
|
93
|
+
Run.kubectl "set image deployments,cronjobs *=#{Config.get!(:image)}:#{revision} --all"
|
85
94
|
end
|
86
95
|
|
87
96
|
desc "release", "Builds and publishes docker images"
|
@@ -97,11 +106,11 @@ module Vidar
|
|
97
106
|
method_option :success_color, required: false
|
98
107
|
method_option :error_color, required: false
|
99
108
|
def monitor_deploy_status
|
100
|
-
Log.info "Current cluster_name: #{Config.get!(:cluster_name)}
|
109
|
+
Log.info "Current cluster_name: #{Config.get!(:cluster_name)}"
|
101
110
|
Log.info "Checking is all containers on #{Config.get!(:cluster_name)} in #{Config.get!(:namespace)} are ready..."
|
102
111
|
|
103
112
|
slack_notification = SlackNotification.new(
|
104
|
-
webhook_url: Config.get
|
113
|
+
webhook_url: Config.get(:slack_webhook_url),
|
105
114
|
github: Config.get!(:github),
|
106
115
|
revision: Config.get!(:revision),
|
107
116
|
revision_name: Config.get!(:revision_name),
|
@@ -111,13 +120,15 @@ module Vidar
|
|
111
120
|
error_color: options[:error_color],
|
112
121
|
)
|
113
122
|
|
114
|
-
|
123
|
+
deploy_status = Vidar::DeployStatus.new(namespace: Config.get!(:namespace))
|
124
|
+
|
125
|
+
deploy_status.wait_until_completed
|
115
126
|
|
116
|
-
if
|
117
|
-
Log.info "OK: All containers are ready
|
127
|
+
if deploy_status.success?
|
128
|
+
Log.info "OK: All containers are ready"
|
118
129
|
slack_notification.success if slack_notification.configured?
|
119
130
|
else
|
120
|
-
Log.error "ERROR: Some of containers are not ready
|
131
|
+
Log.error "ERROR: Some of containers are errored or not ready"
|
121
132
|
slack_notification.error if slack_notification.configured?
|
122
133
|
exit(1)
|
123
134
|
end
|
data/lib/vidar/deploy_status.rb
CHANGED
@@ -4,32 +4,39 @@ module Vidar
|
|
4
4
|
SLEEP = 10
|
5
5
|
MAX_TRIES = 30
|
6
6
|
|
7
|
-
attr_reader :namespace
|
7
|
+
attr_reader :namespace, :filter, :max_tries
|
8
8
|
|
9
|
-
def initialize(namespace)
|
9
|
+
def initialize(namespace:, filter: nil, max_tries: MAX_TRIES)
|
10
10
|
@namespace = namespace
|
11
|
+
@filter = filter
|
12
|
+
@max_tries = max_tries
|
11
13
|
end
|
12
14
|
|
13
|
-
def
|
14
|
-
any_errors = false
|
15
|
+
def wait_until_completed
|
15
16
|
tries = 0
|
16
17
|
|
17
18
|
sleep(INITIAL_SLEEP)
|
18
19
|
|
19
|
-
until
|
20
|
+
until pod_set.deployed?
|
20
21
|
tries += 1
|
21
22
|
sleep(SLEEP)
|
22
|
-
if tries >
|
23
|
-
any_errors = true
|
23
|
+
if tries > max_tries
|
24
24
|
break
|
25
25
|
end
|
26
26
|
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def success?
|
30
|
+
return false unless last_pod_set
|
31
|
+
last_pod_set.success?
|
32
|
+
end
|
27
33
|
|
28
|
-
|
34
|
+
def last_pod_set
|
35
|
+
@pod_set
|
29
36
|
end
|
30
37
|
|
31
|
-
def
|
32
|
-
|
38
|
+
def pod_set
|
39
|
+
@pod_set = K8s::PodSet.new(namespace: namespace, filter: filter)
|
33
40
|
end
|
34
41
|
end
|
35
42
|
end
|
@@ -1,20 +1,31 @@
|
|
1
1
|
module Vidar
|
2
2
|
module K8s
|
3
3
|
class ContainerStatus
|
4
|
-
|
4
|
+
JOB_KIND = "Job".freeze
|
5
|
+
|
6
|
+
attr_reader :data, :state, :namespace, :kind
|
5
7
|
|
6
8
|
def initialize(data)
|
7
|
-
@data
|
8
|
-
@state
|
9
|
+
@data = data
|
10
|
+
@state = data["state"]
|
9
11
|
@namespace = data["namespace"]
|
12
|
+
@kind = data["kind"]
|
10
13
|
end
|
11
14
|
|
12
15
|
def name
|
13
16
|
data["name"]
|
14
17
|
end
|
15
18
|
|
16
|
-
def
|
17
|
-
|
19
|
+
def deployed?
|
20
|
+
return terminated? if job?
|
21
|
+
|
22
|
+
ready? && running?
|
23
|
+
end
|
24
|
+
|
25
|
+
def success?
|
26
|
+
return terminated_completed? if job?
|
27
|
+
|
28
|
+
ready? && running?
|
18
29
|
end
|
19
30
|
|
20
31
|
def print
|
@@ -37,13 +48,13 @@ module Vidar
|
|
37
48
|
[ColorizedString["Not ready"].light_red, "Started at: #{running_started_at}"]
|
38
49
|
end
|
39
50
|
elsif terminated_completed?
|
40
|
-
[ColorizedString["Terminated/Completed"].light_green, "Finished at: #{terminated_finished_at}"]
|
51
|
+
[ColorizedString["Terminated/Completed"].light_green, terminated_finished_at ? "Finished at: #{terminated_finished_at}" : ""]
|
41
52
|
elsif terminated_error?
|
42
|
-
[ColorizedString["Terminated/Error"].light_red]
|
53
|
+
[ColorizedString["Terminated/Error"].light_red, ""]
|
43
54
|
elsif waiting?
|
44
|
-
[ColorizedString["Waiting"].light_green]
|
55
|
+
[ColorizedString["Waiting"].light_green, ""]
|
45
56
|
else
|
46
|
-
[ColorizedString[state.inspect].light_red]
|
57
|
+
[ColorizedString[state.inspect].light_red, ""]
|
47
58
|
end
|
48
59
|
end
|
49
60
|
|
@@ -63,6 +74,10 @@ module Vidar
|
|
63
74
|
state.dig("running", "startedAt")
|
64
75
|
end
|
65
76
|
|
77
|
+
def terminated?
|
78
|
+
!state["terminated"].nil?
|
79
|
+
end
|
80
|
+
|
66
81
|
def terminated_completed?
|
67
82
|
state.dig("terminated", "reason") == "Completed" || state.dig("terminated", "exitCode") == 0
|
68
83
|
end
|
@@ -74,6 +89,10 @@ module Vidar
|
|
74
89
|
def terminated_error?
|
75
90
|
state.dig("terminated", "reason") == "Error" || state.dig("terminated", "exitCode")
|
76
91
|
end
|
92
|
+
|
93
|
+
def job?
|
94
|
+
kind == JOB_KIND
|
95
|
+
end
|
77
96
|
end
|
78
97
|
end
|
79
98
|
end
|
@@ -0,0 +1,72 @@
|
|
1
|
+
module Vidar
|
2
|
+
module K8s
|
3
|
+
class PodSet
|
4
|
+
def initialize(namespace:, filter: nil)
|
5
|
+
@namespace = namespace
|
6
|
+
@filter = filter
|
7
|
+
end
|
8
|
+
|
9
|
+
def deployed?
|
10
|
+
if items.empty?
|
11
|
+
Log.error "Could not fetch pod list"
|
12
|
+
return false
|
13
|
+
end
|
14
|
+
|
15
|
+
Log.line
|
16
|
+
|
17
|
+
container_statuses.each(&:print)
|
18
|
+
|
19
|
+
Log.line
|
20
|
+
|
21
|
+
container_statuses.all?(&:deployed?)
|
22
|
+
end
|
23
|
+
|
24
|
+
def success?
|
25
|
+
container_statuses.all?(&:success?)
|
26
|
+
end
|
27
|
+
|
28
|
+
private
|
29
|
+
|
30
|
+
attr_reader :namespace, :filter
|
31
|
+
|
32
|
+
def items
|
33
|
+
@items ||= begin
|
34
|
+
json = JSON.parse(kubectl_get.strip)
|
35
|
+
json["items"] || []
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def kubectl_get
|
40
|
+
if namespace == "all"
|
41
|
+
`kubectl get pods --all-namespaces -o json`
|
42
|
+
else
|
43
|
+
`kubectl get pods -n #{namespace} -o json`
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def container_statuses
|
48
|
+
return all_container_statuses unless filter
|
49
|
+
|
50
|
+
all_container_statuses.select { |cs| cs.name.to_s.include?(filter) }
|
51
|
+
end
|
52
|
+
|
53
|
+
def all_container_statuses
|
54
|
+
@all_container_statuses ||= container_statuses_data.map { |status| ContainerStatus.new(status) }
|
55
|
+
end
|
56
|
+
|
57
|
+
def container_statuses_data
|
58
|
+
items.map do |i|
|
59
|
+
owner_references = i.dig("metadata", "ownerReferences") || []
|
60
|
+
kind = (owner_references[0] || {})["kind"]
|
61
|
+
namespace = i.dig("metadata", "namespace")
|
62
|
+
statuses = i.dig("status", "containerStatuses") || []
|
63
|
+
statuses.each do |s|
|
64
|
+
s["namespace"] = namespace
|
65
|
+
s["kind"] = kind
|
66
|
+
end
|
67
|
+
statuses
|
68
|
+
end.flatten
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
data/lib/vidar/log.rb
CHANGED
@@ -6,11 +6,11 @@ module Vidar
|
|
6
6
|
end
|
7
7
|
|
8
8
|
def info(text, fill_with = "#")
|
9
|
-
puts ColorizedString["#{fill_with} #{text} ".ljust(
|
9
|
+
puts ColorizedString["#{fill_with} #{text} ".ljust(124, fill_with)].colorize(:light_green)
|
10
10
|
end
|
11
11
|
|
12
12
|
def error(text, fill_with = "#")
|
13
|
-
puts ColorizedString["#{fill_with} #{text} ".ljust(
|
13
|
+
puts ColorizedString["#{fill_with} #{text} ".ljust(124, fill_with)].colorize(:light_red)
|
14
14
|
end
|
15
15
|
end
|
16
16
|
end
|
data/lib/vidar/version.rb
CHANGED
data/vidar.gemspec
CHANGED
@@ -28,6 +28,7 @@ Gem::Specification.new do |spec|
|
|
28
28
|
spec.add_dependency 'faraday'
|
29
29
|
spec.add_dependency 'thor', '~> 0.20'
|
30
30
|
|
31
|
+
spec.add_development_dependency 'awesome_print'
|
31
32
|
spec.add_development_dependency 'bundler'
|
32
33
|
spec.add_development_dependency 'pry'
|
33
34
|
spec.add_development_dependency 'rake'
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: vidar
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Krzysztof Knapik
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: exe
|
11
11
|
cert_chain: []
|
12
|
-
date: 2019-
|
12
|
+
date: 2019-10-01 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: colorize
|
@@ -53,6 +53,20 @@ dependencies:
|
|
53
53
|
- - "~>"
|
54
54
|
- !ruby/object:Gem::Version
|
55
55
|
version: '0.20'
|
56
|
+
- !ruby/object:Gem::Dependency
|
57
|
+
name: awesome_print
|
58
|
+
requirement: !ruby/object:Gem::Requirement
|
59
|
+
requirements:
|
60
|
+
- - ">="
|
61
|
+
- !ruby/object:Gem::Version
|
62
|
+
version: '0'
|
63
|
+
type: :development
|
64
|
+
prerelease: false
|
65
|
+
version_requirements: !ruby/object:Gem::Requirement
|
66
|
+
requirements:
|
67
|
+
- - ">="
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: '0'
|
56
70
|
- !ruby/object:Gem::Dependency
|
57
71
|
name: bundler
|
58
72
|
requirement: !ruby/object:Gem::Requirement
|
@@ -166,7 +180,7 @@ files:
|
|
166
180
|
- lib/vidar/deploy_status.rb
|
167
181
|
- lib/vidar/interpolation.rb
|
168
182
|
- lib/vidar/k8s/container_status.rb
|
169
|
-
- lib/vidar/k8s/
|
183
|
+
- lib/vidar/k8s/pod_set.rb
|
170
184
|
- lib/vidar/log.rb
|
171
185
|
- lib/vidar/run.rb
|
172
186
|
- lib/vidar/slack_notification.rb
|
data/lib/vidar/k8s/pods.rb
DELETED
@@ -1,56 +0,0 @@
|
|
1
|
-
module Vidar
|
2
|
-
module K8s
|
3
|
-
class Pods
|
4
|
-
def initialize(namespace)
|
5
|
-
@namespace = namespace
|
6
|
-
end
|
7
|
-
|
8
|
-
def all_ready?
|
9
|
-
if items.empty?
|
10
|
-
Log.error "Could not fetch pod list"
|
11
|
-
return false
|
12
|
-
end
|
13
|
-
|
14
|
-
Log.line
|
15
|
-
|
16
|
-
container_statuses.each(&:print)
|
17
|
-
|
18
|
-
Log.line
|
19
|
-
|
20
|
-
container_statuses.all?(&:ok?)
|
21
|
-
end
|
22
|
-
|
23
|
-
private
|
24
|
-
|
25
|
-
attr_reader :namespace
|
26
|
-
|
27
|
-
def items
|
28
|
-
@items ||= begin
|
29
|
-
json = JSON.parse(kubectl_get.strip)
|
30
|
-
json["items"] || []
|
31
|
-
end
|
32
|
-
end
|
33
|
-
|
34
|
-
def kubectl_get
|
35
|
-
if namespace == 'all'
|
36
|
-
`kubectl get pods --all-namespaces -o json`
|
37
|
-
else
|
38
|
-
`kubectl get pods -n #{namespace} -o json`
|
39
|
-
end
|
40
|
-
end
|
41
|
-
|
42
|
-
def container_statuses
|
43
|
-
@container_statuses ||= container_statuses_data.map { |status| ContainerStatus.new(status) }
|
44
|
-
end
|
45
|
-
|
46
|
-
def container_statuses_data
|
47
|
-
items.map do |i|
|
48
|
-
namespace = i.dig("metadata", "namespace")
|
49
|
-
statuses = i.dig("status", "containerStatuses") || []
|
50
|
-
statuses.each { |s| s["namespace"] = namespace }
|
51
|
-
statuses
|
52
|
-
end.flatten
|
53
|
-
end
|
54
|
-
end
|
55
|
-
end
|
56
|
-
end
|