aggkit 0.2.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.
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: []