oye 0.1.1 → 0.1.2
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/Gemfile.lock +1 -1
- data/README.md +2 -0
- data/lib/oye.rb +156 -40
- data/lib/oye/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: bd9695ade1c74d7e4a4c0593cd39f0e559f94a3242586e905d33eb66dbc30f49
|
4
|
+
data.tar.gz: ca15ae1503c2fe6777c0a3f9dfc1a7be7a8975407931c8d192930a0524812ef3
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e59fb07e4d00d6551cbec9edd4524da762bedb0641cc27e546d11f809d7424b6b995180d66ee0f4b425a646806e381a8699a112c8136977bf23c9967c03d39a5
|
7
|
+
data.tar.gz: '009310c48f9299dc31750fcb4fbc5316a1b2f52e3a1ae48973e2eab950ce563ddf6cc065c7896a4dc355ec6a2bdcd65bef73d4e52d74eabf4bf17a03a8d9c810'
|
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -7,3 +7,5 @@ A continuous monitoring tool that does a few things:
|
|
7
7
|
3. restarts the rails app with the new code
|
8
8
|
|
9
9
|
[ ] use multithreaading. each thread should watch a unique repo.
|
10
|
+
[ ] run rails tests inside Oye.monitor
|
11
|
+
[ ] check for irregularities in @repos, e.g two repeated cloned repos
|
data/lib/oye.rb
CHANGED
@@ -2,11 +2,16 @@ $LOAD_PATH.unshift __dir__
|
|
2
2
|
|
3
3
|
require "oye/version"
|
4
4
|
require 'fileutils'
|
5
|
+
require 'yaml'
|
5
6
|
|
6
7
|
module Oye
|
7
8
|
class Error < StandardError; end
|
8
9
|
|
9
|
-
|
10
|
+
DEFAULT_WATCH_INTERVAL = 5
|
11
|
+
DEFAULT_PORT = 3000
|
12
|
+
DEFAULT_ENVIRONMENTS = %w(development production test)
|
13
|
+
LOG_FORMAT = "[%Y-%m-%d %H:%M:%S]"
|
14
|
+
|
10
15
|
|
11
16
|
class << self
|
12
17
|
def start(args)
|
@@ -18,97 +23,136 @@ module Oye
|
|
18
23
|
|
19
24
|
FileUtils.mkdir_p(oyedir)
|
20
25
|
|
26
|
+
@repos = {}
|
21
27
|
read_config
|
22
28
|
|
23
29
|
list if(args.include?('-l') or args.include?('--list'))
|
24
30
|
|
25
31
|
if(args.include?('-i') or args.include?('--info'))
|
26
32
|
args.map! {|a| a == '--info' ? '-i' : a}
|
27
|
-
_, @pattern = args.slice
|
33
|
+
_, @pattern = args.slice(args.index('-i'),2)
|
28
34
|
@pattern = @pattern.nil? ? /.*/ : Regexp.new(@pattern)
|
29
35
|
info
|
30
36
|
end
|
31
37
|
|
38
|
+
@interval = DEFAULT_WATCH_INTERVAL
|
32
39
|
if(args.include?('-t') or args.include?('--time'))
|
33
40
|
args.map! {|a| a == '--time' ? '-t' : a}
|
34
|
-
_, @interval = args.slice
|
41
|
+
_, @interval = args.slice(args.index('-t'),2)
|
35
42
|
@interval = @interval.to_i
|
43
|
+
unless @interval > 0
|
44
|
+
puts "Interval must a positive integer"
|
45
|
+
exit
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
@port = DEFAULT_PORT
|
50
|
+
if(args.include?('-p') or args.include?('--port'))
|
51
|
+
args.map! {|a| a == '--port' ? '-p' : a}
|
52
|
+
_, @port = args.slice(args.index('-p'),2)
|
53
|
+
@port = @port.to_i
|
54
|
+
unless @port > 0
|
55
|
+
puts "Port must a positive integer"
|
56
|
+
exit
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
@environment = 'production'
|
61
|
+
if(args.include?('-e') or args.include?('--environment'))
|
62
|
+
args.map! {|a| a == '--environment' ? '-e' : a}
|
63
|
+
_, @environment = args.slice(args.index('-e'),2)
|
64
|
+
unless DEFAULT_ENVIRONMENTS.include?(@environment)
|
65
|
+
puts "Specify a supported environment for -e option"
|
66
|
+
exit
|
67
|
+
end
|
36
68
|
end
|
37
69
|
|
38
70
|
monitor
|
39
71
|
end
|
40
72
|
|
41
73
|
def read_config
|
42
|
-
|
43
|
-
|
44
|
-
YAML.load(File.open(oye_config)).each do |origin, clone|
|
45
|
-
@repos[origin] = {'clone' => clone}
|
74
|
+
YAML.load(File.open(oye_config)).each do |origin, clones|
|
75
|
+
@repos[origin] = {'clones' => clones}
|
46
76
|
end
|
47
77
|
end
|
48
78
|
|
49
79
|
def help
|
50
80
|
puts <<~eos
|
51
|
-
-c, --config print config and
|
81
|
+
-c, --config print config, log and pid files
|
82
|
+
-e, --environment ENV environment for the app server [development|production|test] (default production)
|
52
83
|
-h, --help print this message
|
53
84
|
-i, --info [PATTERN] print info of repos matching PATTERN (default .*)
|
54
85
|
-l, --list print monitored repos
|
86
|
+
-p, --port PORT port for app server (default 3000)
|
55
87
|
-r, --restart restart oye
|
56
88
|
-s, --stop stop oye
|
57
|
-
-t, --time
|
89
|
+
-t, --time SECS time interval for repo monitoring (default 5)
|
58
90
|
-v, --version print oye version
|
59
91
|
eos
|
60
92
|
exit
|
61
93
|
end
|
62
94
|
|
63
|
-
def restart_clone
|
64
|
-
system("cd #{File.dirname(@repos[repo]['clone']}")
|
65
|
-
system("git pull")
|
66
|
-
system("kill $(cat pids/*)")
|
67
|
-
system("unicorn_rails -l 178.128.15.65:3001 -c config/unicorn.rb -E production -D")
|
68
|
-
end
|
69
|
-
|
70
95
|
def monitor
|
71
96
|
trap('TERM') { exit }
|
72
97
|
trap('INT') { exit }
|
73
98
|
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
repos_dup.keys.filter_map do |repo|
|
78
|
-
unless File.exists?(repo)
|
79
|
-
not_found << @repos.delete(repo)
|
80
|
-
next
|
81
|
-
end
|
82
|
-
|
83
|
-
@repos[repo]['stat'] = File.stat(repo).ctime
|
84
|
-
end
|
99
|
+
@repos.keys.filter_map do |origin|
|
100
|
+
next unless File.exists?(origin)
|
85
101
|
|
86
|
-
|
87
|
-
puts "\nWARNING Could not find repos:", not_found
|
102
|
+
@repos[origin]['stat'] = File.stat(origin).ctime
|
88
103
|
end
|
89
104
|
|
90
|
-
log_format = "[%Y-%m-%d %H:%M:%S]"
|
91
|
-
|
92
105
|
pid = fork do
|
93
106
|
begin
|
107
|
+
# initialize apps if they are not running
|
108
|
+
# TODO i dont like this loop
|
109
|
+
@repos.values.flatten.each do |app|
|
110
|
+
app['clones'].each do |clone|
|
111
|
+
|
112
|
+
if !File.exists?(clone)
|
113
|
+
log(clone, status: :warn, message: "Could not find repo")
|
114
|
+
next
|
115
|
+
elsif !File.exists?(app_pid_dir(clone))
|
116
|
+
log(clone, status: :warn, message: "Could not find pids directory")
|
117
|
+
next
|
118
|
+
elsif File.exists?(app_pid_file(clone))
|
119
|
+
# if pid fle exists, the app should be running and there's no need to be initialize it
|
120
|
+
next
|
121
|
+
end
|
122
|
+
|
123
|
+
initialize_clone(clone)
|
124
|
+
|
125
|
+
rescue Errno::ESRCH
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
94
129
|
loop do
|
95
130
|
repos_dup = @repos
|
96
|
-
repos_dup.each do |
|
97
|
-
unless
|
98
|
-
|
131
|
+
repos_dup.keys.each do |origin|
|
132
|
+
unless File.exists?(origin)
|
133
|
+
log(origin, {status: :warn, message: "Could not find repo"})
|
134
|
+
next
|
135
|
+
end
|
99
136
|
|
100
|
-
|
101
|
-
|
137
|
+
repos_dup[origin]['clones'].each do |clone|
|
138
|
+
unless File.exists?(clone)
|
139
|
+
log(clone, {status: :warn, message: "Could not find repo"})
|
140
|
+
next
|
102
141
|
end
|
103
142
|
|
104
|
-
|
143
|
+
unless @repos[origin]['stat'] == File.stat(origin).ctime
|
144
|
+
@repos[origin]['stat'] = File.stat(origin).ctime
|
145
|
+
stop_clone(clone) if File.exists?(app_pid_file(clone))
|
146
|
+
update_clone(clone)
|
147
|
+
initialize_clone(clone)
|
148
|
+
end
|
105
149
|
end
|
106
150
|
end
|
107
151
|
sleep @interval
|
108
152
|
end
|
109
|
-
rescue => e
|
110
|
-
abort "There was a fatal system error while starting oye: #{e.message}, #{caller}"
|
111
153
|
end
|
154
|
+
rescue => e
|
155
|
+
abort "Fatal system error while initializing oye: #{e.message}, #{caller}"
|
112
156
|
end
|
113
157
|
|
114
158
|
File.open(oye_pidfile, 'w') { |f| f.puts pid }
|
@@ -116,14 +160,59 @@ module Oye
|
|
116
160
|
::Process.detach pid
|
117
161
|
end
|
118
162
|
|
163
|
+
def log(repo, options = {})
|
164
|
+
log_message = [
|
165
|
+
Time.now.strftime(LOG_FORMAT),
|
166
|
+
repo,
|
167
|
+
"[#{options[:status].to_s.upcase}]",
|
168
|
+
"\"#{options[:message]}\""
|
169
|
+
].join(' ')
|
170
|
+
|
171
|
+
File.open(oye_logfile, 'a') do |f|
|
172
|
+
f.puts log_message
|
173
|
+
end
|
174
|
+
end
|
175
|
+
|
176
|
+
def initialize_clone(dir)
|
177
|
+
Dir.chdir(dir) do
|
178
|
+
%x(bundle)
|
179
|
+
|
180
|
+
%x(RAILS_ENV=#{@environment} rails db:migrate)
|
181
|
+
|
182
|
+
if @environment == 'production'
|
183
|
+
%x(RAILS_ENV=production rails assets:{clean,precompile})
|
184
|
+
end
|
185
|
+
end
|
186
|
+
|
187
|
+
%x{unicorn_rails -l :#{@port} -c #{unicorn_file(dir)} -E #{@environment} -D}
|
188
|
+
rescue => e
|
189
|
+
log(dir, status: :warn, message: "#{__method__.to_s} (#{e.message})")
|
190
|
+
end
|
191
|
+
|
192
|
+
def stop_clone(dir)
|
193
|
+
Process.kill 'TERM', app_pid(dir)
|
194
|
+
end
|
195
|
+
|
196
|
+
def update_clone(dir)
|
197
|
+
system("git -C #{dir} pull", [:out, :err] => File::NULL)
|
198
|
+
|
199
|
+
log(dir, status: :info, message: "Pulled from origin")
|
200
|
+
rescue => e
|
201
|
+
log(dir, status: :warn, message: "#{__method__.to_s} (#{e.message})")
|
202
|
+
end
|
203
|
+
|
119
204
|
def list
|
120
|
-
|
205
|
+
@repos.each do |origin, clones|
|
206
|
+
puts origin
|
207
|
+
clones.values.flatten.map {|clone| puts clone.prepend " - "}
|
208
|
+
end
|
121
209
|
exit
|
122
210
|
end
|
123
211
|
|
124
212
|
def config
|
125
213
|
puts "Config file: #{oye_config}"
|
126
214
|
puts "Log file: #{oye_logfile}"
|
215
|
+
puts "PID file: #{oye_pidfile}"
|
127
216
|
exit
|
128
217
|
end
|
129
218
|
|
@@ -162,12 +251,18 @@ module Oye
|
|
162
251
|
exit
|
163
252
|
end
|
164
253
|
|
254
|
+
# TODO ensure that pid corresponds to 'oye' process. maybe check
|
255
|
+
# command name like 'ps(1)'
|
165
256
|
def stop
|
257
|
+
Process.kill oye_pid
|
166
258
|
end
|
167
259
|
|
260
|
+
# TODO implement
|
168
261
|
def restart
|
169
262
|
end
|
170
263
|
|
264
|
+
private
|
265
|
+
|
171
266
|
def oyedir
|
172
267
|
"#{ENV['HOME']}/.oye"
|
173
268
|
end
|
@@ -184,5 +279,26 @@ module Oye
|
|
184
279
|
def oye_pidfile
|
185
280
|
"#{oyedir}/oye.pid"
|
186
281
|
end
|
282
|
+
|
283
|
+
def oye_pid
|
284
|
+
File.read(oye_pidfile).to_i
|
285
|
+
end
|
286
|
+
|
287
|
+
|
288
|
+
def unicorn_file(dir)
|
289
|
+
File.join(dir, "config/unicorn.rb")
|
290
|
+
end
|
291
|
+
|
292
|
+
def app_pid(dir)
|
293
|
+
File.read(app_pid_file(dir)).to_i
|
294
|
+
end
|
295
|
+
|
296
|
+
def app_pid_file(dir)
|
297
|
+
File.join(app_pid_dir(dir), "unicorn.pid")
|
298
|
+
end
|
299
|
+
|
300
|
+
def app_pid_dir(dir)
|
301
|
+
File.join(dir, "pids")
|
302
|
+
end
|
187
303
|
end
|
188
304
|
end
|
data/lib/oye/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: oye
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- sergioro
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-05-
|
11
|
+
date: 2020-05-22 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: benchmark-ips
|