aggkit 0.2.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (58) hide show
  1. checksums.yaml +7 -0
  2. data/.dockerignore +20 -0
  3. data/.gitignore +109 -0
  4. data/.gitlab-ci.yml +66 -0
  5. data/.rspec +4 -0
  6. data/.rubocop.yml +98 -0
  7. data/.travis.yml +30 -0
  8. data/Gemfile +12 -0
  9. data/Gemfile.lock +55 -0
  10. data/README.md +96 -0
  11. data/aggkit.gemspec +38 -0
  12. data/bin/agg +167 -0
  13. data/bin/aggconsul +222 -0
  14. data/bin/agglock +71 -0
  15. data/bin/aggmerge +118 -0
  16. data/bin/aggwait +262 -0
  17. data/bin/consul.rb +222 -0
  18. data/bin/locker.rb +71 -0
  19. data/bin/merger.rb +118 -0
  20. data/bin/terminator.rb +71 -0
  21. data/bin/waiter.rb +262 -0
  22. data/docker/Dockerfile +112 -0
  23. data/docker/docker-compose.yml +12 -0
  24. data/docker/down.sh +4 -0
  25. data/docker/run_tests.sh +23 -0
  26. data/lib/aggkit/childprocess/abstract_io.rb +38 -0
  27. data/lib/aggkit/childprocess/abstract_process.rb +194 -0
  28. data/lib/aggkit/childprocess/errors.rb +28 -0
  29. data/lib/aggkit/childprocess/jruby/io.rb +17 -0
  30. data/lib/aggkit/childprocess/jruby/process.rb +161 -0
  31. data/lib/aggkit/childprocess/jruby/pump.rb +55 -0
  32. data/lib/aggkit/childprocess/jruby.rb +58 -0
  33. data/lib/aggkit/childprocess/tools/generator.rb +148 -0
  34. data/lib/aggkit/childprocess/unix/fork_exec_process.rb +72 -0
  35. data/lib/aggkit/childprocess/unix/io.rb +22 -0
  36. data/lib/aggkit/childprocess/unix/lib.rb +188 -0
  37. data/lib/aggkit/childprocess/unix/platform/i386-linux.rb +14 -0
  38. data/lib/aggkit/childprocess/unix/platform/i386-solaris.rb +13 -0
  39. data/lib/aggkit/childprocess/unix/platform/x86_64-linux.rb +14 -0
  40. data/lib/aggkit/childprocess/unix/platform/x86_64-macosx.rb +13 -0
  41. data/lib/aggkit/childprocess/unix/posix_spawn_process.rb +135 -0
  42. data/lib/aggkit/childprocess/unix/process.rb +91 -0
  43. data/lib/aggkit/childprocess/unix.rb +11 -0
  44. data/lib/aggkit/childprocess/version.rb +5 -0
  45. data/lib/aggkit/childprocess/windows/handle.rb +93 -0
  46. data/lib/aggkit/childprocess/windows/io.rb +25 -0
  47. data/lib/aggkit/childprocess/windows/lib.rb +418 -0
  48. data/lib/aggkit/childprocess/windows/process.rb +132 -0
  49. data/lib/aggkit/childprocess/windows/process_builder.rb +177 -0
  50. data/lib/aggkit/childprocess/windows/structs.rb +151 -0
  51. data/lib/aggkit/childprocess/windows.rb +35 -0
  52. data/lib/aggkit/childprocess.rb +213 -0
  53. data/lib/aggkit/env.rb +219 -0
  54. data/lib/aggkit/runner.rb +80 -0
  55. data/lib/aggkit/version.rb +5 -0
  56. data/lib/aggkit/watcher.rb +239 -0
  57. data/lib/aggkit.rb +15 -0
  58. metadata +196 -0
@@ -0,0 +1,239 @@
1
+ #!/usr/bin/env ruby
2
+ require 'English'
3
+
4
+ module Aggkit
5
+
6
+ class Watcher
7
+
8
+
9
+ def initialize
10
+ @lock = Mutex.new
11
+
12
+ @procs = []
13
+ @code = 0
14
+ @crashed = false
15
+ @threads = []
16
+ @who = nil
17
+ @stopping = false
18
+ end
19
+
20
+ def stop_all
21
+ @stopping = true
22
+
23
+ terminating = @procs.reject do |meta|
24
+ meta[:handled] || meta[:process].exited?
25
+ end
26
+
27
+ terminating.each do |meta|
28
+ begin
29
+ meta[:stdin].close
30
+ rescue StandardError
31
+ nil
32
+ end
33
+ if meta[:termcmd].is_a? String
34
+ log "Terminating by #{meta[:termcmd].gsub('%PID%', meta[:process].pid.to_s)}..."
35
+ output = `#{meta[:termcmd].gsub('%PID%', meta[:process].pid.to_s)}`
36
+ if $?.success?
37
+ log "ok: #{output}"
38
+ else
39
+ log "Error: #{output}"
40
+ ::Process.kill 'TERM', meta[:process].pid
41
+ end
42
+ else
43
+ ::Process.kill 'TERM', meta[:process].pid
44
+ end
45
+ end
46
+
47
+ terminating.each do |meta|
48
+ begin
49
+ meta[:process].poll_for_exit(5)
50
+ rescue ChildProcess::TimeoutError
51
+ meta[:process].stop(1)
52
+ meta[:stdout].close
53
+ meta[:stderr].close
54
+ end
55
+ end
56
+
57
+ unless @crashed
58
+ meta = @procs.detect do |meta|
59
+ meta[:process].crashed?
60
+ end
61
+
62
+ if meta
63
+ @crashed = true
64
+ @code = meta[:process].exit_code
65
+ @who = meta[:cmd]
66
+ end
67
+ end
68
+
69
+ @procs.each do |meta|
70
+ begin
71
+ meta[:stdout].close
72
+ rescue StandardError
73
+ nil
74
+ end
75
+ begin
76
+ meta[:stderr].close
77
+ rescue StandardError
78
+ nil
79
+ end
80
+ end
81
+
82
+ Thread.new do
83
+ sleep 2
84
+ @threads.each(&:terminate)
85
+ end
86
+ end
87
+
88
+ def add(*cmd)
89
+ options = cmd.last
90
+ if options.is_a? Hash
91
+ cmd.pop
92
+ else
93
+ options = {}
94
+ end
95
+
96
+ cmd = cmd.flatten.map{|c| c.to_s.strip }.reject(&:empty?)
97
+ process = ChildProcess.build(*cmd)
98
+
99
+ rerr, werr = IO.pipe
100
+ rout, wout = IO.pipe
101
+
102
+ process.io.stdout = wout
103
+ process.io.stderr = werr
104
+ process.duplex = true
105
+
106
+ meta = {
107
+ cmd: cmd,
108
+ process: process,
109
+ stdout: rout,
110
+ stderr: rerr,
111
+ stdin: process.io.stdin,
112
+ termcmd: options[:termcmd]
113
+ }
114
+
115
+ @threads << Thread.new(meta[:stdout], STDOUT) do |io, out|
116
+ loop do
117
+ break unless synchro_readline(io, out)
118
+ end
119
+ end
120
+
121
+ @threads << Thread.new(meta[:stderr], STDERR) do |io, out|
122
+ loop do
123
+ break unless synchro_readline(io, out)
124
+ end
125
+ end
126
+
127
+ log "Starting #{meta[:cmd]}"
128
+ meta[:pid] = meta[:process].start.pid
129
+
130
+ @procs.push(meta)
131
+ meta
132
+ end
133
+
134
+ def synchro_readline(io, out)
135
+ str = io.gets
136
+ @lock.synchronize{ out.puts str }
137
+ true
138
+ rescue StandardError => e
139
+ false
140
+ end
141
+
142
+ def log(msg)
143
+ puts "[watcher]: #{msg}"
144
+ end
145
+
146
+ def error(msg)
147
+ STDERR.puts "[watcher]: Error: #{msg}"
148
+ end
149
+
150
+ def exec
151
+ %w[EXIT QUIT].each do |sig|
152
+ trap(sig) do
153
+ stop_all
154
+ end
155
+ end
156
+
157
+
158
+ %w[INT TERM].each do |sig|
159
+ trap(sig) do
160
+ log "Catch #{sig}: try exits gracefully.."
161
+ stop_all
162
+ end
163
+ end
164
+
165
+ trap('CLD') do |*_args|
166
+ unhandled = @procs.reject do |meta|
167
+ meta[:handled] || !meta[:process].exited?
168
+ end
169
+
170
+ completed = unhandled.any? do |meta|
171
+ log 'Child finished'
172
+ log " Process[#{meta[:pid]}]: #{meta[:cmd]}"
173
+ log " status: #{meta[:process].crashed? ? 'crashed' : 'exited'}"
174
+ log " code: #{meta[:process].exit_code}"
175
+
176
+ meta[:handled] = true
177
+ begin
178
+ meta[:stdin].close
179
+ rescue StandardError
180
+ nil
181
+ end
182
+ begin
183
+ meta[:stdout].close
184
+ rescue StandardError
185
+ nil
186
+ end
187
+ begin
188
+ meta[:stderr].close
189
+ rescue StandardError
190
+ nil
191
+ end
192
+
193
+ if !@crashed && meta[:process].crashed?
194
+ @crashed = true
195
+ @code = meta[:process].exit_code
196
+ @who = meta[:cmd]
197
+ end
198
+
199
+ unless @stopping
200
+ log 'Try exits gracefully..'
201
+ stop_all
202
+ end
203
+
204
+ true
205
+ end
206
+
207
+ unless completed
208
+ begin
209
+ pid, status = Process.waitpid2(-1, Process::WNOHANG)
210
+ rescue StandardError
211
+ nil
212
+ end
213
+ log "Subprocess finished: #{status.inspect}" if status
214
+ end
215
+ end
216
+
217
+ begin
218
+ yield(self)
219
+ rescue StandardError => e
220
+ @crashed = true
221
+ @code = 1
222
+ error e.inspect
223
+ error e.backtrace.last(20).join("\n")
224
+ log 'Try exits gracefully..'
225
+ stop_all
226
+ end
227
+
228
+ @threads.map(&:join)
229
+
230
+ @code = [@code || 0, 1].max if @crashed
231
+
232
+ exit(@code || 0)
233
+ end
234
+
235
+
236
+
237
+ end
238
+
239
+ end
data/lib/aggkit.rb ADDED
@@ -0,0 +1,15 @@
1
+ require 'diplomat'
2
+ require 'English'
3
+ require 'optparse'
4
+ require 'dotenv'
5
+
6
+
7
+ require 'aggkit/version'
8
+ require 'aggkit/watcher'
9
+ require 'aggkit/runner'
10
+ require 'aggkit/env'
11
+ require 'aggkit/childprocess'
12
+
13
+ module Aggkit
14
+
15
+ end
metadata ADDED
@@ -0,0 +1,196 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: aggkit
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.2.5
5
+ platform: ruby
6
+ authors:
7
+ - Godko Ivan
8
+ - Samoilenko Yuri
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2019-02-06 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: diplomat
16
+ requirement: !ruby/object:Gem::Requirement
17
+ requirements:
18
+ - - ">="
19
+ - !ruby/object:Gem::Version
20
+ version: '0'
21
+ type: :runtime
22
+ prerelease: false
23
+ version_requirements: !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - ">="
26
+ - !ruby/object:Gem::Version
27
+ version: '0'
28
+ - !ruby/object:Gem::Dependency
29
+ name: dotenv
30
+ requirement: !ruby/object:Gem::Requirement
31
+ requirements:
32
+ - - ">="
33
+ - !ruby/object:Gem::Version
34
+ version: '0'
35
+ type: :runtime
36
+ prerelease: false
37
+ version_requirements: !ruby/object:Gem::Requirement
38
+ requirements:
39
+ - - ">="
40
+ - !ruby/object:Gem::Version
41
+ version: '0'
42
+ - !ruby/object:Gem::Dependency
43
+ name: json
44
+ requirement: !ruby/object:Gem::Requirement
45
+ requirements:
46
+ - - ">="
47
+ - !ruby/object:Gem::Version
48
+ version: '0'
49
+ type: :runtime
50
+ prerelease: false
51
+ version_requirements: !ruby/object:Gem::Requirement
52
+ requirements:
53
+ - - ">="
54
+ - !ruby/object:Gem::Version
55
+ version: '0'
56
+ - !ruby/object:Gem::Dependency
57
+ name: tty-tree
58
+ requirement: !ruby/object:Gem::Requirement
59
+ requirements:
60
+ - - ">="
61
+ - !ruby/object:Gem::Version
62
+ version: '0'
63
+ type: :runtime
64
+ prerelease: false
65
+ version_requirements: !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - ">="
68
+ - !ruby/object:Gem::Version
69
+ version: '0'
70
+ - !ruby/object:Gem::Dependency
71
+ name: bundler
72
+ requirement: !ruby/object:Gem::Requirement
73
+ requirements:
74
+ - - "~>"
75
+ - !ruby/object:Gem::Version
76
+ version: '1.14'
77
+ type: :development
78
+ prerelease: false
79
+ version_requirements: !ruby/object:Gem::Requirement
80
+ requirements:
81
+ - - "~>"
82
+ - !ruby/object:Gem::Version
83
+ version: '1.14'
84
+ - !ruby/object:Gem::Dependency
85
+ name: rake
86
+ requirement: !ruby/object:Gem::Requirement
87
+ requirements:
88
+ - - "~>"
89
+ - !ruby/object:Gem::Version
90
+ version: '10.0'
91
+ type: :development
92
+ prerelease: false
93
+ version_requirements: !ruby/object:Gem::Requirement
94
+ requirements:
95
+ - - "~>"
96
+ - !ruby/object:Gem::Version
97
+ version: '10.0'
98
+ description: Advanced docker and consul control scripts
99
+ email:
100
+ - igodko@rnds.pro
101
+ - kinnalru@gmail.com
102
+ executables:
103
+ - agg
104
+ - aggconsul
105
+ - agglock
106
+ - aggmerge
107
+ - aggwait
108
+ - consul.rb
109
+ - locker.rb
110
+ - merger.rb
111
+ - terminator.rb
112
+ - waiter.rb
113
+ extensions: []
114
+ extra_rdoc_files: []
115
+ files:
116
+ - ".dockerignore"
117
+ - ".gitignore"
118
+ - ".gitlab-ci.yml"
119
+ - ".rspec"
120
+ - ".rubocop.yml"
121
+ - ".travis.yml"
122
+ - Gemfile
123
+ - Gemfile.lock
124
+ - README.md
125
+ - aggkit.gemspec
126
+ - bin/agg
127
+ - bin/aggconsul
128
+ - bin/agglock
129
+ - bin/aggmerge
130
+ - bin/aggwait
131
+ - bin/consul.rb
132
+ - bin/locker.rb
133
+ - bin/merger.rb
134
+ - bin/terminator.rb
135
+ - bin/waiter.rb
136
+ - docker/Dockerfile
137
+ - docker/docker-compose.yml
138
+ - docker/down.sh
139
+ - docker/run_tests.sh
140
+ - lib/aggkit.rb
141
+ - lib/aggkit/childprocess.rb
142
+ - lib/aggkit/childprocess/abstract_io.rb
143
+ - lib/aggkit/childprocess/abstract_process.rb
144
+ - lib/aggkit/childprocess/errors.rb
145
+ - lib/aggkit/childprocess/jruby.rb
146
+ - lib/aggkit/childprocess/jruby/io.rb
147
+ - lib/aggkit/childprocess/jruby/process.rb
148
+ - lib/aggkit/childprocess/jruby/pump.rb
149
+ - lib/aggkit/childprocess/tools/generator.rb
150
+ - lib/aggkit/childprocess/unix.rb
151
+ - lib/aggkit/childprocess/unix/fork_exec_process.rb
152
+ - lib/aggkit/childprocess/unix/io.rb
153
+ - lib/aggkit/childprocess/unix/lib.rb
154
+ - lib/aggkit/childprocess/unix/platform/i386-linux.rb
155
+ - lib/aggkit/childprocess/unix/platform/i386-solaris.rb
156
+ - lib/aggkit/childprocess/unix/platform/x86_64-linux.rb
157
+ - lib/aggkit/childprocess/unix/platform/x86_64-macosx.rb
158
+ - lib/aggkit/childprocess/unix/posix_spawn_process.rb
159
+ - lib/aggkit/childprocess/unix/process.rb
160
+ - lib/aggkit/childprocess/version.rb
161
+ - lib/aggkit/childprocess/windows.rb
162
+ - lib/aggkit/childprocess/windows/handle.rb
163
+ - lib/aggkit/childprocess/windows/io.rb
164
+ - lib/aggkit/childprocess/windows/lib.rb
165
+ - lib/aggkit/childprocess/windows/process.rb
166
+ - lib/aggkit/childprocess/windows/process_builder.rb
167
+ - lib/aggkit/childprocess/windows/structs.rb
168
+ - lib/aggkit/env.rb
169
+ - lib/aggkit/runner.rb
170
+ - lib/aggkit/version.rb
171
+ - lib/aggkit/watcher.rb
172
+ homepage: https://br.rnds.pro/aggredator/support/aggkit
173
+ licenses:
174
+ - MIT
175
+ metadata: {}
176
+ post_install_message:
177
+ rdoc_options: []
178
+ require_paths:
179
+ - lib
180
+ required_ruby_version: !ruby/object:Gem::Requirement
181
+ requirements:
182
+ - - ">="
183
+ - !ruby/object:Gem::Version
184
+ version: 2.0.0
185
+ required_rubygems_version: !ruby/object:Gem::Requirement
186
+ requirements:
187
+ - - ">="
188
+ - !ruby/object:Gem::Version
189
+ version: '0'
190
+ requirements: []
191
+ rubyforge_project:
192
+ rubygems_version: 2.7.3
193
+ signing_key:
194
+ specification_version: 4
195
+ summary: Helper scripts for work with docker and consul in Aggredator
196
+ test_files: []