Permalink
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
294 lines (242 sloc) 7.89 KB
require 'sinatra/base'
require 'mustache/sinatra'
require 'deployinator'
require 'deployinator/controller'
require 'deployinator/helpers'
require 'deployinator/helpers/deploy'
require 'deployinator/helpers/version'
require 'deployinator/helpers/git'
require 'deployinator/helpers/plugin'
require 'deployinator/views/log'
require 'deployinator/views/run_logs'
require 'deployinator/views/log_table'
require 'deployinator/views/deploys_status'
require 'deployinator/views/stats'
require 'deployinator/views/maintenance'
require 'deployinator/views/stack_down'
module Deployinator
class DeployinatorApp < Sinatra::Base
register Mustache::Sinatra
helpers Deployinator::Helpers,
Deployinator::Helpers::DeployHelpers,
Deployinator::Helpers::GitHelpers,
Deployinator::Helpers::VersionHelpers,
Deployinator::Helpers::PluginHelpers
def github_diff_url(params)
stack = params[:stack].intern
gh_info = git_info_for_stack[stack]
"https://#{which_github_host(stack)}/#{gh_info[:user]}/#{gh_info[:repository]}/compare/#{params[:r1]}...#{params[:r2]}"
end
set :mustache, {
:views => Deployinator.root('views'),
:templates => Deployinator.root('templates'),
:namespace => Deployinator::Views
}
set :public_folder, Deployinator.root('public')
set :static, true
before do
register_plugins(nil)
init(env)
@disabled_override = params[:override].nil? ? false : true
pass if [
"/maintenance",
"/css/maintenance.css",
"/images/maintenance.gif",
"/static/css/style.css"
].include? request.path_info
if Deployinator.maintenance_mode == true && !is_admin?
redirect "/maintenance"
end
end
before do
end
get '/' do
mustache Deployinator.index_view_class
end
get '/stats' do
mustache Deployinator::Views::Stats
end
get '/maintenance' do
mustache Deployinator::Views::Maintenance
end
get '/run_logs/view/:log' do
template = open("#{File.dirname(__FILE__)}/templates/stream.mustache").read
template.gsub!("{{ yield }}", "{{{yield}}}")
Mustache.render(template, :yield => open("run_logs/" + params[:log]).read)
end
get '/run_logs/?' do
@stack = "log"
@params = params
mustache Deployinator::Views::RunLogs
end
get '/run_logs/latest/:log_type' do
run_logs = get_run_logs(:limit => 1, :type => params[:log_type])
if run_logs.count == 1
run_log = run_logs.first[:name]
redirect "/run_logs/view/#{run_log}"
else
redirect "/"
end
end
get '/log/?' do
@stack = "log"
@params = params
mustache Deployinator::Views::LogTable
end
get '/:stack/can-deploy' do
lock_info = pushes_locked?(params["stack"]) || {}
lock_info[:can_deploy] = lock_info.empty?
lock_info[:all_locked] = !(all_pushes_locked? == nil)
content_type "application/json"
lock_info.to_json
end
get '/diff/:stack/:r1/:r2/?' do
@stack = params[:stack]
diff(params["r1"], params["r2"], params["stack"], params[:time])
end
get '/diff/:stack/:r1/:r2/github/?' do
redirect github_diff_url(params)
end
get '/head_rev/:stack' do
git_head_rev(params[:stack]).chomp
end
get '/:stack/remove-lock' do
stack = params[:stack]
unlock_pushes(stack) if can_remove_stack_lock?
redirect "/#{stack}"
end
# lock all stacks
get '/lockall' do
lock_all_pushes(@username)
if params[:stack]
redirect "/#{params[:stack]}"
else
redirect "/"
end
end
# unlock all stacks
get '/unlockall' do
unlock_all_pushes()
if params[:stack]
redirect "/#{params[:stack]}"
else
redirect "/"
end
end
# return a list of all deploys as JSON
get '/deploys/?' do
get_list_of_deploys.to_json
end
get '/static/css/style.css?:version' do
send_file "#{File.dirname(__FILE__)}/static/css/style.css"
end
get '/static/css/diff_style.css' do
send_file "#{File.dirname(__FILE__)}/static/css/diff_style.css"
end
get '/static/css/highlight.css' do
send_file "#{File.dirname(__FILE__)}/static/css/highlight.css"
end
get '/css/maintenance.css' do
send_file "#{File.dirname(__FILE__)}/static/css/maintenance.css"
end
get '/js/flot/jquery.flot.min.js' do
send_file "#{File.dirname(__FILE__)}/static/js/flot/jquery.flot.min.js"
end
get '/js/flot/jquery.flot.selection.js' do
send_file "#{File.dirname(__FILE__)}/static/js/flot/jquery.flot.selection.js"
end
get '/js/jquery-1.8.3.min.js' do
send_file "#{File.dirname(__FILE__)}/static/js/jquery-1.8.3.min.js"
end
get '/js/jquery-ui-1.8.24.min.js' do
send_file "#{File.dirname(__FILE__)}/static/js/jquery-ui-1.8.24.min.js"
end
get '/static/css/jquery-ui-1.8.24.css' do
send_file "#{File.dirname(__FILE__)}/static/css/jquery-ui-1.8.24.css"
end
get '/static/css/images/ui-icons_0078ae_256x240.png' do
send_file "#{File.dirname(__FILE__)}/static/css/images/ui-icons_0078ae_256x240.png"
end
get '/js/jquery.timed_bar.js' do
send_file "#{File.dirname(__FILE__)}/static/js/jquery.timed_bar.js"
end
get '/js/stats_load.js' do
send_file "#{File.dirname(__FILE__)}/static/js/stats_load.js"
end
get '/images/maintenance.gif' do
send_file "#{File.dirname(__FILE__)}/static/images/maintenance.gif"
end
get '/deploys_status' do
mustache Deployinator::Views::DeploysStatus
end
get '/log.txt' do
content_type :text
`tac #{Deployinator.log_path}#{ " | head -n #{params[:limit]}" if params[:limit]}`
end
get '/timing_log.txt' do
content_type :text
`tac #{Deployinator.timing_log_path}`
end
get '/ti/:stack/:env' do
@stack = params[:stack]
average_duration(params["env"], params["stack"]).to_s
end
# this is the API endpoint to asynchronously start a deploy that runs in
# the background.
post '/deploys/?' do
params[:username] = @username
params[:groups] = @groups
params[:block] = Proc.new { |line| foo = line }
deploy_running = is_deploy_active?(params[:stack], params[:stage])
# if this deploy is already running, return 403
if deploy_running
return 403
end
pid = fork {
Signal.trap("HUP") { exit }
Deployinator.setup_logging
$0 = get_deploy_process_title(params[:stack], params[:stage])
controller = Deployinator.deploy_controller || Deployinator::Controller
d = controller.new
d.run(params)
}
Process.detach(pid)
200
end
delete '/deploys/?' do
return 400 if (params[:stack].nil? || params[:stage].nil?)
res = stop_deploy(params[:stack], params[:stage])
unless res
return 404
end
200
end
get %r{/(\w+)/(versions|builds)} do |stack, type|
type = type.gsub(/s$/, '')
content_type :json
inst = mustache_class(stack, settings.mustache).new
# Sinatra's mustache helper usually shoves all instance variables into the view but we aren't using that here
inst.set_stack(stack)
meth = "#{stack}_%s_#{type}"
inst.push_order.collect {|env| [env, inst.send(meth % env)]}.to_json
end
get '/:thing' do
@stack = params[:thing]
unless Deployinator.get_visible_stacks.include?(@stack)
raise Sinatra::NotFound, "No such stack #{@stack}"
end
@params = params
found_stack_info = Deployinator.disabled_stacks.find {|ds| ds.name.to_s == @stack}
unless found_stack_info.nil?
@stack_info = found_stack_info
next mustache Deployinator::Views::StackDown
end
register_plugins(@stack)
begin
mustache @stack
rescue Errno::ENOENT
pass
end
end
end
end