aggkit 0.3.1.8768 → 0.3.4
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 +5 -5
- data/.rubocop.yml +27 -4
- data/Gemfile +3 -0
- data/Gemfile.lock +12 -6
- data/aggkit.gemspec +3 -2
- data/bin/agg +52 -33
- data/bin/aggci +31 -26
- data/bin/aggconsul +16 -15
- data/bin/agggen +31 -34
- data/bin/agglock +5 -4
- data/bin/aggmerge +33 -28
- data/bin/aggstart +19 -22
- data/bin/aggterm +3 -2
- data/bin/aggwait +5 -3
- data/bin/aggwrap +250 -0
- data/lib/aggkit/ci.rb +62 -67
- data/lib/aggkit/env.rb +119 -103
- data/lib/aggkit/option_parser.rb +10 -7
- data/lib/aggkit/runner.rb +2 -3
- data/lib/aggkit/version.rb +2 -1
- data/lib/aggkit/watcher.rb +5 -4
- data/lib/aggkit.rb +1 -0
- metadata +5 -3
data/bin/agggen
CHANGED
@@ -7,65 +7,65 @@ require 'optparse'
|
|
7
7
|
UTIL = File.basename(__FILE__)
|
8
8
|
|
9
9
|
@opts = {
|
10
|
-
token:
|
10
|
+
token: ENV['GITLAB_API_PRIVATE_TOKEN'] || ENV['BOT_TOKEN'] || ENV['TOKEN'],
|
11
11
|
endpoint: 'https://br.rnds.pro/api/v4',
|
12
|
-
exclude:
|
13
|
-
gtmpl:
|
14
|
-
ptmpl:
|
12
|
+
exclude: 'core/mq,core/auth,core/ca,core/router,core/admin,core/filator',
|
13
|
+
gtmpl: '%name%:%id%',
|
14
|
+
ptmpl: '%badge% %name%:%id%'
|
15
15
|
}
|
16
16
|
|
17
17
|
|
18
18
|
@dynamic = {
|
19
|
-
badge:
|
19
|
+
badge: proc do |object|
|
20
20
|
"#{object.web_url}/badges/master/pipeline.svg"
|
21
21
|
end,
|
22
|
-
pipeline:
|
22
|
+
pipeline: proc do |object|
|
23
23
|
"#{object.web_url}/pipelines"
|
24
24
|
end,
|
25
|
-
redmine_badge:
|
25
|
+
redmine_badge: proc do |object|
|
26
26
|
"!#{object.web_url}/badges/master/pipeline.svg!:#{object.web_url}/pipelines"
|
27
27
|
end,
|
28
|
-
redmine_link:
|
28
|
+
redmine_link: proc do |object|
|
29
29
|
"\"#{object.name}\":#{object.web_url}"
|
30
30
|
end,
|
31
31
|
|
32
|
-
gitlab_link:
|
32
|
+
gitlab_link: proc do |object|
|
33
33
|
"[#{object.name}](#{object.web_url})"
|
34
34
|
end,
|
35
|
-
gitlab_badge:
|
35
|
+
gitlab_badge: proc do |object|
|
36
36
|
"[](#{object.web_url})"
|
37
|
-
end
|
37
|
+
end
|
38
38
|
}
|
39
39
|
|
40
40
|
@tempaltes = {
|
41
|
-
redmine:
|
41
|
+
redmine: '|%redmine_badge%|%redmine_link%|%description%|',
|
42
42
|
gredmine: "\n|*%name%*||%description%|",
|
43
|
-
gitlab:
|
44
|
-
ggitlab:
|
43
|
+
gitlab: '* [ ] %gitlab_link% %description%',
|
44
|
+
ggitlab: "\n**%name%**"
|
45
45
|
}
|
46
46
|
|
47
47
|
parser = OptionParser.new do |o|
|
48
48
|
o.banner = "Usage: #{UTIL} [options]"
|
49
49
|
|
50
|
-
o.on(
|
50
|
+
o.on('--list', 'list projects') do
|
51
51
|
@opts[:list] = true
|
52
52
|
end
|
53
53
|
|
54
|
-
o.on(
|
54
|
+
o.on('--groups groups', 'process only these groups') do |groups|
|
55
55
|
@opts[:groups] = groups.to_s.split(/[ ,;|]/).map(&:to_s).reject(&:empty?).uniq
|
56
56
|
end
|
57
57
|
|
58
|
-
o.on(
|
58
|
+
o.on('--gtmpl template', 'template to print group') do |tmpl|
|
59
59
|
tmpl = @tempaltes[tmpl.to_s.to_sym] || tmpl
|
60
60
|
@opts[:gtmpl] = tmpl.to_s
|
61
61
|
end
|
62
62
|
|
63
|
-
o.on(
|
63
|
+
o.on('--ptmpl template', 'template to print projects') do |tmpl|
|
64
64
|
tmpl = @tempaltes[tmpl.to_s.to_sym] || tmpl
|
65
65
|
@opts[:ptmpl] = tmpl.to_s
|
66
66
|
end
|
67
67
|
|
68
|
-
o.on(
|
68
|
+
o.on('--exclude projects', 'exclude projects from selection') do |exclude|
|
69
69
|
@opts[:exclude] = exclude.to_s
|
70
70
|
end
|
71
71
|
|
@@ -73,23 +73,22 @@ parser = OptionParser.new do |o|
|
|
73
73
|
@opts[:endpoint] = endpoint.to_s.strip
|
74
74
|
end
|
75
75
|
|
76
|
-
o.on(
|
76
|
+
o.on('--token token', 'set api token') do |token|
|
77
77
|
@opts[:token] = token.to_s.strip
|
78
78
|
end
|
79
|
-
|
80
79
|
end
|
81
80
|
parser.parse!
|
82
81
|
|
83
82
|
@api = Gitlab.client(endpoint: @opts[:endpoint], private_token: @opts[:token])
|
84
83
|
|
85
|
-
MAIN_GROUP='aggredator'
|
84
|
+
MAIN_GROUP = 'aggredator'.freeze
|
86
85
|
|
87
86
|
|
88
87
|
|
89
|
-
def each_group
|
88
|
+
def each_group(group)
|
90
89
|
Enumerator.new do |y|
|
91
90
|
y << group
|
92
|
-
|
91
|
+
|
93
92
|
@api.group_subgroups(group.id, per_page: 1000).each do |sub|
|
94
93
|
each_group(sub).each do |g|
|
95
94
|
y << g
|
@@ -98,7 +97,7 @@ def each_group group
|
|
98
97
|
end
|
99
98
|
end
|
100
99
|
|
101
|
-
def each_project
|
100
|
+
def each_project(group)
|
102
101
|
Enumerator.new do |y|
|
103
102
|
@api.group_projects(group.id, per_page: 1000).each do |p|
|
104
103
|
y << p
|
@@ -106,17 +105,16 @@ def each_project group
|
|
106
105
|
end
|
107
106
|
end
|
108
107
|
|
109
|
-
def inspect_group
|
108
|
+
def inspect_group(group)
|
110
109
|
result = {}
|
111
110
|
result[:groups] = @api.group_subgroups(group.id).each_with_object({}) do |sub, ret|
|
112
111
|
ret[sub.name] = inspect_group(sub)
|
113
112
|
end
|
114
|
-
result[:projects]
|
113
|
+
result[:projects] = @api.group_projects(group.id).map(&:name)
|
115
114
|
result
|
116
115
|
end
|
117
116
|
|
118
|
-
|
119
|
-
def render tmpl, substs, object
|
117
|
+
def render(tmpl, substs, object)
|
120
118
|
substs.reduce(tmpl) do |ret, s|
|
121
119
|
if callable = @dynamic[s.to_sym]
|
122
120
|
ret.gsub("%#{s}%", callable.call(object).to_s)
|
@@ -129,9 +127,9 @@ end
|
|
129
127
|
|
130
128
|
|
131
129
|
if @opts[:list]
|
132
|
-
gsubsts = @opts[:gtmpl].scan(/%\w+%/).map{|pattern| pattern[/\w+/]}
|
133
|
-
psubsts = @opts[:ptmpl].scan(/%\w+%/).map{|pattern| pattern[/\w+/]}
|
134
|
-
|
130
|
+
gsubsts = @opts[:gtmpl].scan(/%\w+%/).map{|pattern| pattern[/\w+/] }
|
131
|
+
psubsts = @opts[:ptmpl].scan(/%\w+%/).map{|pattern| pattern[/\w+/] }
|
132
|
+
|
135
133
|
|
136
134
|
main = @api.groups(search: MAIN_GROUP).first
|
137
135
|
|
@@ -158,7 +156,7 @@ if @opts[:list]
|
|
158
156
|
puts line
|
159
157
|
end
|
160
158
|
end
|
161
|
-
|
159
|
+
|
162
160
|
exit 0
|
163
161
|
end
|
164
162
|
|
@@ -166,4 +164,3 @@ end
|
|
166
164
|
STDERR.puts parser.help
|
167
165
|
exit 1
|
168
166
|
|
169
|
-
|
data/bin/agglock
CHANGED
@@ -4,9 +4,9 @@ require 'optparse'
|
|
4
4
|
require 'diplomat'
|
5
5
|
|
6
6
|
@opts = {
|
7
|
-
url:
|
7
|
+
url: 'http://localhost:8500',
|
8
8
|
timeout: 10,
|
9
|
-
ttl:
|
9
|
+
ttl: 30 * 60
|
10
10
|
}
|
11
11
|
|
12
12
|
parser = OptionParser.new do |o|
|
@@ -48,9 +48,9 @@ end
|
|
48
48
|
|
49
49
|
if resource = @opts[:lock]
|
50
50
|
locker = {
|
51
|
-
Name:
|
51
|
+
Name: "#{resource}_locker_#{rand(999_999)}",
|
52
52
|
Behavior: 'delete',
|
53
|
-
TTL:
|
53
|
+
TTL: "#{@opts[:ttl]}s",
|
54
54
|
resource: resource
|
55
55
|
}
|
56
56
|
sessionid = Diplomat::Session.create(locker)
|
@@ -69,3 +69,4 @@ else
|
|
69
69
|
STDERR.puts parser.help
|
70
70
|
exit 1
|
71
71
|
end
|
72
|
+
|
data/bin/aggmerge
CHANGED
@@ -40,7 +40,9 @@ def extend_hash(first, second)
|
|
40
40
|
next unless second.key?(fk)
|
41
41
|
|
42
42
|
sv = second[fk]
|
43
|
-
|
43
|
+
if !fv.nil? && !sv.nil? && fv.class != sv.class
|
44
|
+
raise "Types of values not match(#{fv.class}, #{sv.class})" if fv.class != sv.class
|
45
|
+
end
|
44
46
|
|
45
47
|
# Специальный случай потому что command не мерджится а заменяется
|
46
48
|
if fk == 'command'
|
@@ -67,31 +69,32 @@ end
|
|
67
69
|
def process_compose_hash(yml, dirname, parent = {})
|
68
70
|
(yml['services'] || {}).each_pair do |name, service|
|
69
71
|
next unless ext = service['extends']
|
72
|
+
|
70
73
|
base = if ext.is_a? String
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
74
|
+
template = yml['services'][ext]
|
75
|
+
parent_service = (parent['services'] || {})[ext] || {}
|
76
|
+
extend_hash(parent_service.deep_dup, template)
|
77
|
+
elsif file = ext['file']
|
78
|
+
ENV.each_pair do |k, v|
|
79
|
+
file.gsub!("$#{k}", v)
|
80
|
+
file.gsub!("${#{k}}", v)
|
81
|
+
end
|
82
|
+
|
83
|
+
file_to_load = if File.exist?(dirname + '/' + file)
|
84
|
+
dirname + '/' + file
|
85
|
+
else
|
86
|
+
file
|
87
|
+
end
|
88
|
+
|
89
|
+
tmp = process_compose_hash(YAML.load(File.read(file_to_load)), File.dirname(file_to_load), service)
|
90
|
+
|
91
|
+
begin
|
92
|
+
(tmp['services'][ext['service']] || {})
|
93
|
+
rescue StandardError
|
94
|
+
{}
|
95
|
+
end
|
96
|
+
else
|
97
|
+
yml['services'][ext['service']]
|
95
98
|
end.deep_dup
|
96
99
|
|
97
100
|
service.delete 'extends'
|
@@ -101,13 +104,13 @@ def process_compose_hash(yml, dirname, parent = {})
|
|
101
104
|
yml
|
102
105
|
end
|
103
106
|
|
104
|
-
def remove_build_section
|
105
|
-
if hash.
|
107
|
+
def remove_build_section(hash)
|
108
|
+
if hash.key?(:build) || hash.key?('build')
|
106
109
|
hash.delete(:build)
|
107
110
|
hash.delete('build')
|
108
111
|
end
|
109
112
|
|
110
|
-
hash.each_pair do |
|
113
|
+
hash.each_pair do |_k, v|
|
111
114
|
if v.is_a?(Hash)
|
112
115
|
remove_build_section(v)
|
113
116
|
elsif v.is_a?(Array)
|
@@ -124,6 +127,7 @@ if File.basename($PROGRAM_NAME) == File.basename(__FILE__)
|
|
124
127
|
if yml['version'] && parent['version'] && yml['version'] != parent['version']
|
125
128
|
raise "version mismatch: #{file}"
|
126
129
|
end
|
130
|
+
|
127
131
|
ret = extend_hash(parent.deep_dup, yml)
|
128
132
|
ret
|
129
133
|
end
|
@@ -138,3 +142,4 @@ if File.basename($PROGRAM_NAME) == File.basename(__FILE__)
|
|
138
142
|
end
|
139
143
|
|
140
144
|
end
|
145
|
+
|
data/bin/aggstart
CHANGED
@@ -5,16 +5,24 @@ require 'aggkit'
|
|
5
5
|
UTIL = File.basename(__FILE__)
|
6
6
|
|
7
7
|
@opts = {
|
8
|
-
service:
|
9
|
-
consul: ENV['CONSUL_HOST'] || 'localhost',
|
8
|
+
service: ENV['AGGREDATOR_SERVICE'],
|
9
|
+
consul: ENV['CONSUL_HTTP_ADDR'] || ENV['CONSUL_HOST'] || 'localhost',
|
10
10
|
consulconf: [],
|
11
|
-
depends:
|
11
|
+
depends: []
|
12
12
|
}
|
13
13
|
|
14
|
+
@opts[:exec] = (begin
|
15
|
+
idx = ARGV.index {|a| a.strip == '--' } + 1
|
16
|
+
ARGV[idx..-1]
|
17
|
+
rescue StandardError
|
18
|
+
[]
|
19
|
+
end)
|
20
|
+
|
21
|
+
|
14
22
|
parser = Aggkit::OptionParser.new do |o|
|
15
23
|
o.banner = "Usage: #{UTIL} [options]"
|
16
24
|
|
17
|
-
o.on(
|
25
|
+
o.on('--service <NAME>', 'Set service NAME. AGGREDATOR_SERVICE env can be used instead') do |service|
|
18
26
|
@opts[:service] = service.to_s
|
19
27
|
end
|
20
28
|
|
@@ -22,7 +30,7 @@ parser = Aggkit::OptionParser.new do |o|
|
|
22
30
|
@opts[:consul] = consul.to_s
|
23
31
|
end
|
24
32
|
|
25
|
-
o.on(
|
33
|
+
o.on('--consulconf=consul,consul/smev3...', 'Set list of folders with consul configs. Special: none - disable local consul') do |list|
|
26
34
|
@opts[:consulconf] = if list.to_s == 'none'
|
27
35
|
nil
|
28
36
|
else
|
@@ -30,28 +38,18 @@ parser = Aggkit::OptionParser.new do |o|
|
|
30
38
|
end
|
31
39
|
end
|
32
40
|
|
33
|
-
o.on(
|
41
|
+
o.on('--depends=mq,db,router...', 'Set list of services to wait for ready before start') do |list|
|
34
42
|
@opts[:depends] = list.to_s.split(/[ ;,|]/).map(&:to_s).reject(&:empty?)
|
35
43
|
end
|
36
|
-
|
37
|
-
o.on("--exec <FILE>", 'Set FILE to execute.') do |file|
|
38
|
-
@opts[:exec] = file.to_s
|
39
|
-
end
|
40
|
-
|
41
|
-
|
42
44
|
end
|
43
45
|
parser.parse!
|
44
46
|
|
45
47
|
|
46
48
|
include Aggkit::Runner
|
47
49
|
|
48
|
-
if @opts[:service].to_s.empty?
|
49
|
-
die "service name must be provided"
|
50
|
-
end
|
50
|
+
die 'service name must be provided' if @opts[:service].to_s.empty?
|
51
51
|
|
52
|
-
if @opts[:exec].
|
53
|
-
die "exec script must be provided"
|
54
|
-
end
|
52
|
+
die 'exec script must be provided' if @opts[:exec].empty?
|
55
53
|
|
56
54
|
@opts[:node_name] = "#{@opts[:service]}_#{`hostname`.strip}".strip
|
57
55
|
|
@@ -64,7 +62,6 @@ init_service @opts[:service], @opts
|
|
64
62
|
envsubst '/home/app/consul'
|
65
63
|
|
66
64
|
Aggkit::Watcher.new.exec do |watcher|
|
67
|
-
|
68
65
|
if @opts[:consulconf]
|
69
66
|
configs = @opts[:consulconf].map do |folder|
|
70
67
|
"-config-dir #{folder}"
|
@@ -76,9 +73,9 @@ Aggkit::Watcher.new.exec do |watcher|
|
|
76
73
|
if File.exist?('/home/app/docker/start_checker.py')
|
77
74
|
watcher.add '/home/app/docker/start_checker.py'
|
78
75
|
end
|
79
|
-
|
80
76
|
|
81
|
-
|
77
|
+
|
78
|
+
execute!("aggwait -t 20 --consul-addr=http://#{@opts[:consul]}:8500 --consul", 'Timeout for consul service')
|
82
79
|
|
83
80
|
load_envs_from_consul(@opts[:consul], @opts[:service])
|
84
81
|
|
@@ -88,6 +85,6 @@ Aggkit::Watcher.new.exec do |watcher|
|
|
88
85
|
|
89
86
|
sleep 2
|
90
87
|
|
91
|
-
watcher.add
|
88
|
+
watcher.add @opts[:exec]
|
92
89
|
end
|
93
90
|
|
data/bin/aggterm
CHANGED
data/bin/aggwait
CHANGED
@@ -105,9 +105,9 @@ if @opts[:db]
|
|
105
105
|
@pg[:db] = "-d #{@opts[:db]}"
|
106
106
|
@pg[:user] = "-U #{@opts[:user]}" if @opts[:user]
|
107
107
|
@pg[:pass] = if @opts[:pass] && !@opts[:pass].empty?
|
108
|
-
|
109
|
-
|
110
|
-
|
108
|
+
"PGPASSWORD=#{@opts[:pass]}"
|
109
|
+
else
|
110
|
+
''
|
111
111
|
end
|
112
112
|
|
113
113
|
@pg[:host] = "-h #{@opts[:host]}" if @opts[:host]
|
@@ -124,6 +124,7 @@ def wait_for(timeout)
|
|
124
124
|
return success if success
|
125
125
|
|
126
126
|
return false if (Time.now - starttime) > timeout
|
127
|
+
|
127
128
|
sleep @opts[:interval]
|
128
129
|
end
|
129
130
|
|
@@ -280,3 +281,4 @@ if @opts[:docker]
|
|
280
281
|
complete!(success)
|
281
282
|
end
|
282
283
|
end
|
284
|
+
|
data/bin/aggwrap
ADDED
@@ -0,0 +1,250 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'diplomat'
|
4
|
+
require 'securerandom'
|
5
|
+
require 'aggkit'
|
6
|
+
require 'net/http'
|
7
|
+
|
8
|
+
STDERR.sync
|
9
|
+
STDOUT.sync
|
10
|
+
|
11
|
+
UTIL = File.basename(__FILE__)
|
12
|
+
|
13
|
+
@opts = {
|
14
|
+
service: ENV['AGGREDATOR_SERVICE'],
|
15
|
+
id: SecureRandom.hex(8),
|
16
|
+
consul: ENV['CONSUL_HTTP_ADDR'] || ENV['CONSUL_HOST'] || 'localhost'
|
17
|
+
}
|
18
|
+
|
19
|
+
@opts[:exec] = (begin
|
20
|
+
idx = ARGV.index {|a| a.strip == '--' } + 1
|
21
|
+
ARGV[idx..-1]
|
22
|
+
rescue StandardError
|
23
|
+
[]
|
24
|
+
end)
|
25
|
+
|
26
|
+
parser = Aggkit::OptionParser.new do |o|
|
27
|
+
o.banner = "Usage: #{UTIL} [options] -- exec script"
|
28
|
+
|
29
|
+
o.on('--service <NAME>', 'Set service NAME. AGGREDATOR_SERVICE env used when missed') do |service|
|
30
|
+
@opts[:service] = service.to_s
|
31
|
+
end
|
32
|
+
|
33
|
+
o.on('--id <identifier>', 'Set service identifier to concat with name. Random when default') do |id|
|
34
|
+
@opts[:id] = id.to_s
|
35
|
+
end
|
36
|
+
|
37
|
+
o.on("--consul=#{@opts[:consul]}", 'Set consul host. CONSUL_HOST env used when missed') do |consul|
|
38
|
+
@opts[:consul] = consul.to_s
|
39
|
+
Diplomat.configure do |config|
|
40
|
+
config.url = @opts[:consul]
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
o.on('--http <PORT>', 'Create TTL consul check and pass http result to it') do |port|
|
45
|
+
@opts[:http] = port.to_s
|
46
|
+
end
|
47
|
+
|
48
|
+
o.on('--file <FILE>', 'Create TTL consul check and pass file contents to it') do |file|
|
49
|
+
@opts[:file] = file.to_s
|
50
|
+
end
|
51
|
+
|
52
|
+
o.on('--pidfile <FILE>', 'Create TTL consul check and pass pid check(from file) to it') do |file|
|
53
|
+
@opts[:pidfile] = file.to_s
|
54
|
+
end
|
55
|
+
|
56
|
+
o.on('--script <FILE>', 'Create TTL consul check and pass script result to it') do |file|
|
57
|
+
@opts[:script] = file.to_s
|
58
|
+
end
|
59
|
+
end
|
60
|
+
parser.parse!
|
61
|
+
|
62
|
+
die 'service name must be provided' if @opts[:service].to_s.empty?
|
63
|
+
|
64
|
+
die 'script must be provided' if @opts[:exec].empty?
|
65
|
+
|
66
|
+
SERVICE_ID = "#{@opts[:service]}_#{@opts[:id]}".freeze
|
67
|
+
|
68
|
+
@service = {
|
69
|
+
Name: @opts[:service],
|
70
|
+
ID: SERVICE_ID,
|
71
|
+
Checks: []
|
72
|
+
}
|
73
|
+
|
74
|
+
@checks = {}
|
75
|
+
|
76
|
+
|
77
|
+
@checks[:exec] = "#{SERVICE_ID}_exec_ttl"
|
78
|
+
@service[:Checks].push(
|
79
|
+
CheckID: @checks[:exec],
|
80
|
+
Name: "Wrapped service: #{@opts[:service]}. Process: #{@opts[:exec].inspect}",
|
81
|
+
DeregisterCriticalServiceAfter: '1m',
|
82
|
+
TTL: '30s'
|
83
|
+
)
|
84
|
+
|
85
|
+
if @opts[:http]
|
86
|
+
@checks[:http] = "#{SERVICE_ID}_http_ttl"
|
87
|
+
@service[:Checks].push(
|
88
|
+
CheckID: @checks[:http],
|
89
|
+
Name: "Wrapped service: #{@opts[:service]}. HTTP: #{@opts[:http]}",
|
90
|
+
DeregisterCriticalServiceAfter: '1m',
|
91
|
+
TTL: '30s'
|
92
|
+
)
|
93
|
+
end
|
94
|
+
|
95
|
+
if @opts[:file]
|
96
|
+
@checks[:file] = "#{SERVICE_ID}_file_ttl"
|
97
|
+
@service[:Checks].push(
|
98
|
+
CheckID: @checks[:file],
|
99
|
+
Name: "Wrapped service: #{@opts[:service]}. File: #{@opts[:file]}",
|
100
|
+
DeregisterCriticalServiceAfter: '1m',
|
101
|
+
TTL: '30s'
|
102
|
+
)
|
103
|
+
end
|
104
|
+
|
105
|
+
if @opts[:pidfile]
|
106
|
+
@checks[:pidfile] = "#{SERVICE_ID}_pidfile_ttl"
|
107
|
+
@service[:Checks].push(
|
108
|
+
CheckID: @checks[:pidfile],
|
109
|
+
Name: "Wrapped service: #{@opts[:service]}. Pidfile: #{@opts[:pidfile]}",
|
110
|
+
DeregisterCriticalServiceAfter: '1m',
|
111
|
+
TTL: '30s'
|
112
|
+
)
|
113
|
+
end
|
114
|
+
|
115
|
+
if @opts[:script]
|
116
|
+
@checks[:script] = "#{SERVICE_ID}_script_ttl"
|
117
|
+
@service[:Checks].push(
|
118
|
+
CheckID: @checks[:script],
|
119
|
+
Name: "Wrapped service: #{@opts[:service]}. Script: #{@opts[:script]}",
|
120
|
+
DeregisterCriticalServiceAfter: '1m',
|
121
|
+
TTL: '30s'
|
122
|
+
)
|
123
|
+
end
|
124
|
+
|
125
|
+
def make_ttl_pass(check_id, output = nil)
|
126
|
+
STDERR.puts "TTL call failed: #{check_id}" unless Diplomat::Check.pass(check_id, output)
|
127
|
+
end
|
128
|
+
|
129
|
+
def make_ttl_fail(check_id, output = nil)
|
130
|
+
STDERR.puts "TTL call failed: #{check_id}" unless Diplomat::Check.fail(check_id, output)
|
131
|
+
end
|
132
|
+
|
133
|
+
def check_http(check_id, port)
|
134
|
+
response = Net::HTTP.get_response(URI("http://localhost:#{port}"))
|
135
|
+
output = response.body.strip
|
136
|
+
if response.code.to_i < 400
|
137
|
+
make_ttl_pass(check_id, output)
|
138
|
+
else
|
139
|
+
make_ttl_fail(check_id, output)
|
140
|
+
end
|
141
|
+
rescue StandardError => e
|
142
|
+
make_ttl_fail(check_id, e.inspect)
|
143
|
+
end
|
144
|
+
|
145
|
+
def check_file(check_id, file)
|
146
|
+
output = File.read(file).strip
|
147
|
+
make_ttl_pass(check_id, output)
|
148
|
+
rescue StandardError => e
|
149
|
+
make_ttl_fail(check_id, e.inspect)
|
150
|
+
end
|
151
|
+
|
152
|
+
def check_pidfile(check_id, pidfile)
|
153
|
+
pid = Integer(File.read(pidfile).strip)
|
154
|
+
make_ttl_pass(check_id)
|
155
|
+
rescue StandardError => e
|
156
|
+
make_ttl_fail(check_id, e.inspect)
|
157
|
+
end
|
158
|
+
|
159
|
+
def check_script(check_id, script)
|
160
|
+
output = `#{script} 2>&1`.to_s.strip
|
161
|
+
if $?&.success?
|
162
|
+
make_ttl_pass(check_id, output)
|
163
|
+
else
|
164
|
+
make_ttl_fail(check_id, output)
|
165
|
+
end
|
166
|
+
rescue StandardError => e
|
167
|
+
make_ttl_fail(check_id, e.inspect)
|
168
|
+
end
|
169
|
+
|
170
|
+
def run_check(check_id)
|
171
|
+
yield(check_id)
|
172
|
+
rescue StandardError => e
|
173
|
+
STDERR.puts "make_ttl_pass[#{check_id}] Exception: #{e.inspect}"
|
174
|
+
end
|
175
|
+
|
176
|
+
if Diplomat::Service.register(@service)
|
177
|
+
Thread.new do
|
178
|
+
loop do
|
179
|
+
run_check(@checks[:exec]) do |check_id|
|
180
|
+
make_ttl_pass(check_id)
|
181
|
+
end
|
182
|
+
|
183
|
+
if @checks[:http]
|
184
|
+
run_check(@checks[:http]) do |check_id|
|
185
|
+
check_http(check_id, @opts[:http])
|
186
|
+
end
|
187
|
+
end
|
188
|
+
|
189
|
+
if @checks[:file]
|
190
|
+
run_check(@checks[:file]) do |check_id|
|
191
|
+
check_file(check_id, @opts[:file])
|
192
|
+
end
|
193
|
+
end
|
194
|
+
|
195
|
+
if @checks[:pidfile]
|
196
|
+
run_check(@checks[:pidfile]) do |check_id|
|
197
|
+
check_pidfile(check_id, @opts[:pidfile])
|
198
|
+
end
|
199
|
+
end
|
200
|
+
|
201
|
+
if @checks[:script]
|
202
|
+
run_check(@checks[:script]) do |check_id|
|
203
|
+
check_script(check_id, @opts[:script])
|
204
|
+
end
|
205
|
+
end
|
206
|
+
|
207
|
+
sleep 10
|
208
|
+
end
|
209
|
+
end
|
210
|
+
else
|
211
|
+
die "can't register consul service"
|
212
|
+
end
|
213
|
+
|
214
|
+
$pid = fork do
|
215
|
+
exec(*@opts[:exec])
|
216
|
+
end
|
217
|
+
|
218
|
+
%w[INT TERM].each do |sig|
|
219
|
+
trap(sig) do
|
220
|
+
trap(sig, 'SYSTEM_DEFAULT')
|
221
|
+
::Process.kill(sig, $pid)
|
222
|
+
end
|
223
|
+
end
|
224
|
+
|
225
|
+
pid, status = Process.wait2($pid)
|
226
|
+
|
227
|
+
result = {}
|
228
|
+
|
229
|
+
if status
|
230
|
+
if status.signaled?
|
231
|
+
result[:signal] = status.termsig
|
232
|
+
elsif status.exited?
|
233
|
+
result[:exit] = if status.success?
|
234
|
+
0
|
235
|
+
else
|
236
|
+
[status.exitstatus, 2].max
|
237
|
+
end
|
238
|
+
end
|
239
|
+
end
|
240
|
+
|
241
|
+
if result[:signal]
|
242
|
+
trap(result[:signal], 'SYSTEM_DEFAULT')
|
243
|
+
::Process.kill(result[:signal], ::Process.pid)
|
244
|
+
elsif result[:exit]
|
245
|
+
exit(result[:exit])
|
246
|
+
else
|
247
|
+
STDERR.puts 'unknown subprocess result'
|
248
|
+
exit(-1)
|
249
|
+
end
|
250
|
+
|