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.
Files changed (6) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile.lock +1 -1
  3. data/README.md +2 -0
  4. data/lib/oye.rb +156 -40
  5. data/lib/oye/version.rb +1 -1
  6. metadata +2 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ba0137a6da4e4541a1691339760c047d60c4b223aafbdccc7195ceb85ebef815
4
- data.tar.gz: b489de80c32505ff4009e30924ba1e1ba45698b456371a57dc6c917600e7e7ff
3
+ metadata.gz: bd9695ade1c74d7e4a4c0593cd39f0e559f94a3242586e905d33eb66dbc30f49
4
+ data.tar.gz: ca15ae1503c2fe6777c0a3f9dfc1a7be7a8975407931c8d192930a0524812ef3
5
5
  SHA512:
6
- metadata.gz: bdf339dfbbae4ab3e961002c952532ce6aad899ce6f1d453ecf23afbaaa94aed67430cc2fcfca7845a2dba608df6b66e59d95530bf15d6fc0b00c894f707ef52
7
- data.tar.gz: e22782ff4bfcf7f59ea864c52ac72e5469c265e90a0fe4fb21d2fee86b4cb3f85d6c3fef5ed9e44c1a726f6ee0944340d444a39f0495d1b1d128da640b093fb4
6
+ metadata.gz: e59fb07e4d00d6551cbec9edd4524da762bedb0641cc27e546d11f809d7424b6b995180d66ee0f4b425a646806e381a8699a112c8136977bf23c9967c03d39a5
7
+ data.tar.gz: '009310c48f9299dc31750fcb4fbc5316a1b2f52e3a1ae48973e2eab950ce563ddf6cc065c7896a4dc355ec6a2bdcd65bef73d4e52d74eabf4bf17a03a8d9c810'
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- oye (0.1.1)
4
+ oye (0.1.2)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
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
- @interval = 5
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!(args.index('-i'),2)
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!(args.index('-i'),2)
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
- @repos = {}
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 log files
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 [SECS] time interval for repo monitoring (default 5)
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
- not_found = []
75
- repos_dup = @repos
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
- unless not_found.empty?
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 |repo|
97
- unless @repos[repo]['stat'] == File.stat(name).ctime
98
- @repos[repo]['stats'] = File.stat(name).ctime
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
- File.open(oye_logfile, 'a') do |f|
101
- f.puts "#{@repos[repo]['stats'].strftime(log_format)} #{repo}"
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
- restart_clone
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
- puts @repos.keys
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
@@ -1,3 +1,3 @@
1
1
  module Oye
2
- VERSION = "0.1.1"
2
+ VERSION = "0.1.2"
3
3
  end
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.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-21 00:00:00.000000000 Z
11
+ date: 2020-05-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: benchmark-ips