module Oye
Constants
- DEFAULT_ENVIRONMENTS
- DEFAULT_WATCH_INTERVAL
- LOG_FORMAT
- VERSION
Public Class Methods
build_app(dir)
click to toggle source
# File lib/oye.rb, line 179 def build_app(dir) Dir.chdir(dir) do %x(bundle) if rails_app?(dir) %x(RAILS_ENV=#{@environment} rails db:migrate) if @environment == 'production' %x(RAILS_ENV=production rails assets:{clean,precompile}) end elsif jekyll_app?(dir) %x{jekyll build} end end log(dir, status: :info, message: "Built app") rescue => e log(dir, status: :warn, message: "#{__method__.to_s} (#{e.message})") end
config_oye()
click to toggle source
print oye config files
# File lib/oye.rb, line 250 def config_oye puts "Config file: #{oye_config}" puts "Log file: #{oye_logfile}" puts "PID file: #{oye_pidfile}" exit end
help()
click to toggle source
# File lib/oye.rb, line 86 def help puts <<~eos -c, --config print config, log and pid files -e, --environment ENV environment for the app server [development|production|test] (default production) -h, --help print this message -i, --info [PATTERN] print info of repos matching PATTERN (default .*) -l, --list print monitored repos -p, --port PORT port for app server -r, --restart restart oye -s, --stop stop oye -t, --time SECS time interval for repo monitoring (default 5) -v, --version print oye version eos exit end
info()
click to toggle source
print watched repos
# File lib/oye.rb, line 258 def info not_found = [] @repos.keys.each do |repo| next unless repo.match?(@pattern) unless File.exists?(repo) not_found << repo next end ftime=File.stat(repo).ctime # use same format than "ls -l" time_format = if ftime.year == Time.now.year "%b %d %H:%M" else "%b %d %Y" end puts "#{ftime.strftime(time_format)} #{repo}" end unless not_found.empty? puts "\nCould not find repos:", not_found end exit end
list()
click to toggle source
# File lib/oye.rb, line 241 def list @repos.each do |origin, clones| puts origin clones.values.flatten.map {|clone| puts clone.prepend " - "} end exit end
log(repo, options = {})
click to toggle source
# File lib/oye.rb, line 166 def log(repo, options = {}) log_message = [ Time.now.strftime(LOG_FORMAT), repo, "[#{options[:status].to_s.upcase}]", "\"#{options[:message]}\"" ].join(' ') File.open(oye_logfile, 'a') do |f| f.puts log_message end end
monitor()
click to toggle source
main method
# File lib/oye.rb, line 103 def monitor %w(TERM INT).each do |signal| trap(signal) do stop_oye exit end end # get change-times of origin repos @repos.keys.filter_map do |origin| next unless File.exists?(origin) @repos[origin]['stat'] = File.stat(origin).ctime end pid = fork do begin # initial build and start of apps @repos.values.flatten.each do |app| app['clones'].each do |clone| if !File.exists?(clone) log(clone, status: :warn, message: "Could not find repo") next end build_app(clone) start_app(clone) end end # loop that watches for changes in origin repos loop do repos_dup = @repos repos_dup.keys.each do |origin| unless File.exists?(origin) log(origin, {status: :warn, message: "Could not find repo"}) next end repos_dup[origin]['clones'].each do |clone| unless File.exists?(clone) log(clone, {status: :warn, message: "Could not find repo"}) next end unless @repos[origin]['stat'] == File.stat(origin).ctime @repos[origin]['stat'] = File.stat(origin).ctime update_app(clone) build_app(clone) restart_app(clone) end end end sleep @interval end end end File.open(oye_pidfile, 'w') { |f| f.puts pid } ::Process.detach pid end
read_config()
click to toggle source
# File lib/oye.rb, line 80 def read_config YAML.load(File.open(oye_config)).each do |origin, clones| @repos[origin] = {'clones' => clones} end end
restart_app(clone)
click to toggle source
# File lib/oye.rb, line 304 def restart_app(clone) stop_app(clone) start_app(clone) end
restart_oye()
click to toggle source
TODO implement
# File lib/oye.rb, line 301 def restart_oye end
start(args)
click to toggle source
# File lib/oye.rb, line 17 def start(args) help if(args.include?('-h') or args.include?('--help')) version if(args.include?('-v') or args.include?('--version')) restart_oye if(args.include?('-r') or args.include?('--restart')) config_oye if(args.include?('-c') or args.include?('--config')) if(args.include?('-s') or args.include?('--stop')) stop_oye exit end FileUtils.mkdir_p(oyedir) @repos = {} read_config list if(args.include?('-l') or args.include?('--list')) if(args.include?('-i') or args.include?('--info')) args.map! {|a| a == '--info' ? '-i' : a} _, @pattern = args.slice(args.index('-i'),2) @pattern = @pattern.nil? ? /.*/ : Regexp.new(@pattern) info end @interval = DEFAULT_WATCH_INTERVAL if(args.include?('-t') or args.include?('--time')) args.map! {|a| a == '--time' ? '-t' : a} _, @interval = args.slice(args.index('-t'),2) @interval = @interval.to_i unless @interval > 0 puts "Interval must a positive integer" exit end end if(args.include?('-p') or args.include?('--port')) args.map! {|a| a == '--port' ? '-p' : a} _, @port = args.slice(args.index('-p'),2) @port = @port.to_i unless @port > 0 puts "Port must a positive integer" exit end end @environment = 'production' if(args.include?('-e') or args.include?('--environment')) args.map! {|a| a == '--environment' ? '-e' : a} _, @environment = args.slice(args.index('-e'),2) unless DEFAULT_ENVIRONMENTS.include?(@environment) puts "Specify a supported environment for -e option" exit end end @default_unicorn_options = "-E #{@environment} -D" @default_unicorn_options << " -l #{@port}" if @port @default_jekyll_options = "-B" monitor end
start_app(dir)
click to toggle source
# File lib/oye.rb, line 213 def start_app(dir) Dir.chdir(dir) do if rails_app?(dir) unicorn_options = @default_unicorn_options << " -c #{unicorn_file(dir)}" system("unicorn_rails #{unicorn_options}", [:out, :err] => File::NULL) elsif jekyll_app?(dir) if @environment == 'development' jekyll_options = @default_jekyll_options << " -s #{dir} -d #{dir}/_site" system("jekyll serve #{jekyll_options}", [:out, :err] => File::NULL) end end end log(dir, status: :info, message: "Started app") rescue => e log(dir, status: :warn, message: "#{__method__.to_s} (#{e.message})") end
stop_app(dir)
click to toggle source
# File lib/oye.rb, line 199 def stop_app(dir) if rails_app?(dir) if File.exists?(app_pid_file(dir)) Process.kill 'TERM', app_pid(dir) end elsif jekyll_app?(dir) if @environment == 'development' %x(pkill -f jekyll) end end rescue => e log(dir, status: :warn, message: "#{__method__.to_s} (#{e.message})") end
stop_oye()
click to toggle source
# File lib/oye.rb, line 293 def stop_oye Process.kill 'TERM', oye_pid FileUtils.rm_f(oye_pidfile) log(oye_pidfile, status: :info, message: "Stopped oye") rescue Errno::ENOENT end
update_app(dir)
click to toggle source
# File lib/oye.rb, line 233 def update_app(dir) system("git -C #{dir} pull", [:out, :err] => File::NULL) log(dir, status: :info, message: "Pulled from origin") rescue => e log(dir, status: :warn, message: "#{__method__.to_s} (#{e.message})") end
version()
click to toggle source
# File lib/oye.rb, line 288 def version puts "oye #{VERSION}" exit end
Private Class Methods
gemfile(dir)
click to toggle source
# File lib/oye.rb, line 323 def gemfile(dir) File.join(dir, "Gemfile.lock") end
oye_config()
click to toggle source
file with the name of repos that oye
should watch
# File lib/oye.rb, line 349 def oye_config "#{oyedir}/oye.yml" end
oye_logfile()
click to toggle source
log oye
actions
# File lib/oye.rb, line 354 def oye_logfile "#{oyedir}/oye.log" end
oyedir()
click to toggle source
# File lib/oye.rb, line 344 def oyedir "#{ENV['HOME']}/.oye" end
port_open?(port)
click to toggle source
return true
if the port is open else false
# File lib/oye.rb, line 328 def port_open?(port) begin Timeout::timeout(1) do begin s = TCPServer.new(port) s.close return true rescue Errno::ECONNREFUSED, Errno::EHOSTUNREACH, Errno::EADDRINUSE return false end end rescue Timeout::Error end return false end