From 04a17cb69139db580f4b4f0a8ca04af9e4d9d862 Mon Sep 17 00:00:00 2001 From: Pavel Chipiga Date: Tue, 6 Dec 2011 16:45:20 +0200 Subject: [PATCH] Redo deploy to work multistage on same host. Add ui and pingwinsoft stages, Refactor deploy. Refactor XML RPC stub. Apply nginx config generation script. Fix scripts. Cleanup code and config. Refs #2261 --- app/models/download.rb | 6 -- bin/rotate_nginx.sh | 8 +- config/deploy.rb | 84 ++++++++----------- config/deploy/pingwinsoft.rb | 15 ++++ config/deploy/ui.rb | 15 ++++ config/environments/development.rb | 15 +--- config/environments/production.rb | 15 +--- config/environments/test.rb | 16 +--- lib/ext/paperclip.rb | 56 ++++++------- lib/recipes/nginx.rb | 71 ++++++++++++++++ lib/stub_xml_rpc.rb | 14 ++++ .../build_lists_controller_spec.rb | 2 +- 12 files changed, 188 insertions(+), 129 deletions(-) create mode 100644 config/deploy/pingwinsoft.rb create mode 100644 config/deploy/ui.rb create mode 100644 lib/recipes/nginx.rb create mode 100644 lib/stub_xml_rpc.rb diff --git a/app/models/download.rb b/app/models/download.rb index 8dde3a5db..f2b6ce216 100644 --- a/app/models/download.rb +++ b/app/models/download.rb @@ -4,12 +4,6 @@ class Download < ActiveRecord::Base default_scope order(:name) class << self - #def rotate_nginx_log - # system("sudo mv #{ APP_CONFIG['nginx_log'] } #{ PREV_LOG_FILE }") - # #system("sudo kill -USR1 `cat #{ APP_CONFIG['nginx_pid'] }`") - # system("sudo /opt/nginx/sbin/nginx -s reload") - #end - def parse_nginx_log File.open(PREV_LOG_FILE) do |log| while (line = log.gets) diff --git a/bin/rotate_nginx.sh b/bin/rotate_nginx.sh index ea00970a4..f3518c6bb 100755 --- a/bin/rotate_nginx.sh +++ b/bin/rotate_nginx.sh @@ -1,6 +1,6 @@ #!/bin/bash -mv /opt/nginx/logs/access.log /opt/nginx/logs/access.log.0 -/opt/nginx/sbin/nginx -s reload -chown rosa /opt/nginx/logs/access.log.0 -touch /home/rosa/i_was_launched.txt +mv /srv/rosa_build/shared/log/nginx.access.log /srv/rosa_build/shared/log/nginx.access.log.0 +/etc/init.d/nginx reload +chown rosa /srv/rosa_build/shared/log/nginx.access.log.0 +# touch /home/rosa/i_was_launched.txt diff --git a/config/deploy.rb b/config/deploy.rb index b47b4fe5c..53ec0aebf 100644 --- a/config/deploy.rb +++ b/config/deploy.rb @@ -1,66 +1,40 @@ $:.unshift(File.expand_path('./lib', ENV['rvm_path'])) +set :rvm_type, :user require 'rvm/capistrano' require 'bundler/capistrano' +require 'delayed/recipes' require 'airbrake/capistrano' - set :whenever_command, "bundle exec whenever" require "whenever/capistrano" -set :rvm_type, :user - set :default_stage, "staging" -set :stages, %w(production staging) +# set :stages, %w(production staging pingwinsoft ui) # auto readed require 'capistrano/ext/multistage' -# bundler bootstrap - # main details ssh_options[:forward_agent] = true set :application, "rosa_build" +set :deploy_to, "/srv/#{application}" +set :user, "rosa" +set :use_sudo, false +set :keep_releases, 3 set :repository, "git@github.com:warpc/rosa-build.git" # set :git_shallow_clone, 1 set :scm, "git" - -set :user, "rosa" -# set :sudo, "rvmsudo" -set :use_sudo, false -set :deploy_to, "/srv/#{application}" # set :deploy_via, :copy # set :copy_cache, true -set :keep_releases, 3 - -set :rails_env, :production set :unicorn_binary, "bundle exec unicorn" set :unicorn_config, "#{current_path}/config/unicorn.rb" set :unicorn_pid, "#{current_path}/tmp/pids/unicorn.pid" +set :unicorn_port, 8080 -task :symlink_config_files do - run "mkdir -p #{deploy_to}/#{shared_dir}/config" - - run "yes y | cp -i #{release_path}/config/database.yml.sample #{deploy_to}/#{shared_dir}/config/database.yml" - run "yes y | cp -i #{release_path}/config/application.yml.sample #{deploy_to}/#{shared_dir}/config/application.yml" - - - run "ln -nfs #{shared_path}/config/database.yml #{release_path}/config/database.yml" - run "ln -nfs #{shared_path}/config/application.yml #{release_path}/config/application.yml" -end - -task :symlink_downloads_dir do - run "ln -nfs #{shared_path}/downloads/ #{release_path}/public/downloads" -end - -task :symlink_tmp_dir do - run "ln -nfs #{shared_path}/tmp/ #{release_path}/tmp" - run "mkdir -p #{release_path}/tmp/mount" - run "mkdir -p #{release_path}/tmp/umount" -end - +require 'lib/recipes/nginx' namespace :deploy do task :start, :roles => :app, :except => { :no_release => true } do - run "cd #{current_path} && #{try_sudo} #{unicorn_binary} -c #{unicorn_config} -E #{rails_env} -D" + run "cd #{current_path} && #{try_sudo} #{unicorn_binary} -c #{unicorn_config} -p #{unicorn_port} -E #{rails_env} -D" end task :stop, :roles => :app, :except => { :no_release => true } do run "#{try_sudo} kill `cat #{unicorn_pid}`" @@ -74,22 +48,38 @@ namespace :deploy do task :restart, :roles => :app, :except => { :no_release => true } do stop start - # run "touch #{current_release}/tmp/restart.txt" - restart_dj + end + # task :restart, :roles => :app, :except => { :no_release => true } do + # run "touch #{current_release}/tmp/restart.txt" + # end + + task :stub_xml_rpc do + path = File.join(current_path, 'config', 'environment.rb') + code = %Q{\nrequire 'stub_xml_rpc'\n} + puts "Stub XML RPC" + run %Q{echo "#{code}" >> #{path}} end - # %w(start).each { |name| task name, :roles => :app do deploy.restart end } + task :symlink_config_files, :roles => :web do + run "mkdir -p #{deploy_to}/#{shared_dir}/config" - desc "Restart delayed job" - task :restart_dj, :roles => :web do - run "cd #{deploy_to}/current ; RAILS_ENV=production ./script/delayed_job stop; RAILS_ENV=production ./script/delayed_job start; true" + run "yes y | cp -i #{release_path}/config/database.yml.sample #{deploy_to}/#{shared_dir}/config/database.yml" + run "yes y | cp -i #{release_path}/config/application.yml.sample #{deploy_to}/#{shared_dir}/config/application.yml" + + run "ln -nfs #{shared_path}/config/database.yml #{release_path}/config/database.yml" + run "ln -nfs #{shared_path}/config/application.yml #{release_path}/config/application.yml" end - after "deploy:update_code", :roles => :web do - symlink_config_files - symlink_downloads_dir - symlink_tmp_dir + task :symlink_downloads_dir, :roles => :web do + run "ln -nfs #{shared_path}/downloads/ #{release_path}/public/downloads" + end + + task :symlink_tmp_dir, :roles => :web do + run "ln -nfs #{shared_path}/tmp/ #{release_path}/tmp" + run "mkdir -p #{release_path}/tmp/mount" + run "mkdir -p #{release_path}/tmp/umount" end end -after "deploy:update_code", "deploy:migrate" +after "deploy:update_code", "deploy:symlink_config_files", "deploy:symlink_downloads_dir", "deploy:symlink_tmp_dir", "deploy:migrate" +after "deploy:restart", "delayed_job:restart", "deploy:cleanup" diff --git a/config/deploy/pingwinsoft.rb b/config/deploy/pingwinsoft.rb new file mode 100644 index 000000000..ad87b2146 --- /dev/null +++ b/config/deploy/pingwinsoft.rb @@ -0,0 +1,15 @@ +set :branch, "pingwinsoft" + +set :domain, "b.pingwinsoft.ru" # "195.19.76.12" +set :port, 1822 + +role :app, domain +role :web, domain +role :db, domain, :primary => true + +set :application, "rosa_build_#{stage}" +set :deploy_to, "/srv/#{application}" + +set :unicorn_port, 8081 + +before "deploy:restart", "deploy:stub_xml_rpc" diff --git a/config/deploy/ui.rb b/config/deploy/ui.rb new file mode 100644 index 000000000..41cae1601 --- /dev/null +++ b/config/deploy/ui.rb @@ -0,0 +1,15 @@ +set :branch, "ui" + +set :domain, "abf.warpc.ru" # "195.19.76.12" +set :port, 1822 + +role :app, domain +role :web, domain +role :db, domain, :primary => true + +set :application, "rosa_build_#{stage}" +set :deploy_to, "/srv/#{application}" + +set :unicorn_port, 8082 + +before "deploy:restart", "deploy:stub_xml_rpc" diff --git a/config/environments/development.rb b/config/environments/development.rb index c3d314f30..c3cc4ae1e 100644 --- a/config/environments/development.rb +++ b/config/environments/development.rb @@ -24,17 +24,4 @@ Rosa::Application.configure do config.action_dispatch.best_standards_support = :builtin end -# Uncomment this to stub XML RPC calls -require 'xmlrpc/client' -module XMLRPC - class Client - def call(*args) - # raise args.inspect - case - when args.first == 'get_status' - {'client_count' => 1, 'count_new_task' => 2, 'count_build_task' => 3} - else; 0 - end - end - end -end +require 'stub_xml_rpc' diff --git a/config/environments/production.rb b/config/environments/production.rb index e420053a0..f29b78fce 100644 --- a/config/environments/production.rb +++ b/config/environments/production.rb @@ -49,17 +49,4 @@ Rosa::Application.configure do config.active_support.deprecation = :notify end -# Uncomment this to stub XML RPC calls -# require 'xmlrpc/client' -# module XMLRPC -# class Client -# def call(*args) -# # raise args.inspect -# case -# when args.first == 'get_status' -# {'client_count' => 1, 'count_new_task' => 2, 'count_build_task' => 3} -# else; 0 -# end -# end -# end -# end +# require 'stub_xml_rpc' diff --git a/config/environments/test.rb b/config/environments/test.rb index 63a3ed5b6..27fdd7bed 100644 --- a/config/environments/test.rb +++ b/config/environments/test.rb @@ -35,18 +35,4 @@ Rosa::Application.configure do config.active_support.deprecation = :stderr end -# Uncomment this to stub XML RPC calls -require 'xmlrpc/client' -module XMLRPC - class Client - def call(*args) - # raise args.inspect - case - when args.first == 'get_status' - raise Timeout::Error - else; 0 - end - end - end -end - +require 'stub_xml_rpc' diff --git a/lib/ext/paperclip.rb b/lib/ext/paperclip.rb index 665a8995e..aec5f4242 100644 --- a/lib/ext/paperclip.rb +++ b/lib/ext/paperclip.rb @@ -1,29 +1,29 @@ # Patch to use paperclip with nginx upload module -# module Paperclip -# class Attachment -# class UploadedPath -# attr_reader :original_filename, :content_type, :size, :path -# def initialize(uploaded_file) -# @original_filename = uploaded_file["name"].downcase -# @content_type = uploaded_file["content_type"].to_s.strip -# @file_size = uploaded_file["size"].to_i -# @path = uploaded_file["path"] -# end -# -# # TODO remove failed files -# -# def to_tempfile; self; end -# -# def size; @file_size; end -# -# def close; end -# def closed?; true; end -# end -# -# def assign_with_upload(uploaded_file) -# uploaded_file = UploadedPath.new(uploaded_file) if uploaded_file.is_a?(Hash) -# assign_without_upload(uploaded_file) -# end -# alias_method_chain :assign, :upload -# end -# end +module Paperclip + class Attachment + class UploadedPath + attr_reader :original_filename, :content_type, :size, :path + def initialize(uploaded_file) + @original_filename = uploaded_file["name"].downcase + @content_type = uploaded_file["content_type"].to_s.strip + @file_size = uploaded_file["size"].to_i + @path = uploaded_file["path"] + end + + # TODO remove failed files + + def to_tempfile; self; end + + def size; @file_size; end + + def close; end + def closed?; true; end + end + + def assign_with_upload(uploaded_file) + uploaded_file = UploadedPath.new(uploaded_file) if uploaded_file.is_a?(Hash) + assign_without_upload(uploaded_file) + end + alias_method_chain :assign, :upload + end +end diff --git a/lib/recipes/nginx.rb b/lib/recipes/nginx.rb new file mode 100644 index 000000000..0ff8d568d --- /dev/null +++ b/lib/recipes/nginx.rb @@ -0,0 +1,71 @@ +Capistrano::Configuration.instance(:must_exist).load do + namespace :deploy do + namespace :nginx do + set :nginx_init_path, "/etc/init.d/nginx" + + desc "Generate Nginx configuration" + task :generate_configuration, :roles => :web, :except => { :no_release => true } do + cur_path = File.join(deploy_to, current_dir) + nginx_config_path = "/etc/nginx/conf.d/#{application}.conf" + config = %Q{ +upstream #{application}_backend { + server 127.0.0.1:#{unicorn_port}; +} + +server { + listen 80; + server_name #{domain}; + root #{cur_path}/public; + + location /downloads { + autoindex on; + } + + try_files $uri/index.html $uri.html $uri @myapp; + + location @myapp { + proxy_pass http://#{application}_backend; + proxy_set_header Host $host; + proxy_set_header X-Forwarded-For $remote_addr; + proxy_read_timeout 300; + proxy_send_timeout 180; + proxy_redirect off; + } + + access_log #{shared_path}/log/nginx.access.log; + error_log #{shared_path}/log/nginx.error.log; + + error_page 500 502 503 504 /500.html; + location = /500.html { + root #{cur_path}/public; + } +} +} + # puts config + puts "Write nginx config to #{nginx_config_path}" + put config, '/tmp/nginx.conf' + sudo "mv /tmp/nginx.conf #{nginx_config_path}", :pty => true + end + + desc "Start nginx web server" + task :start, :roles => :web, :except => { :no_release => true } do + sudo "#{fetch :nginx_init_path} start" + end + + desc "Stop nginx web server" + task :stop, :roles => :web, :except => { :no_release => true } do + sudo "#{fetch :nginx_init_path} stop" + end + + desc "Restart nginx web server" + task :restart, :roles => :web, :except => { :no_release => true } do + sudo "#{fetch :nginx_init_path} restart" + end + + desc "Resload nginx web server" + task :reload, :roles => :web, :except => { :no_release => true } do + sudo "#{fetch :nginx_init_path} reload" + end + end + end +end diff --git a/lib/stub_xml_rpc.rb b/lib/stub_xml_rpc.rb new file mode 100644 index 000000000..1a5bb33aa --- /dev/null +++ b/lib/stub_xml_rpc.rb @@ -0,0 +1,14 @@ +require 'xmlrpc/client' +module XMLRPC + class Client + def call(*args) + # raise args.inspect + case + when args.first == 'get_status' + {'client_count' => 1, 'count_new_task' => 2, 'count_build_task' => 3} + # raise Timeout::Error + else; 0 + end + end + end +end diff --git a/spec/controllers/build_lists_controller_spec.rb b/spec/controllers/build_lists_controller_spec.rb index 94243e5b4..beb60af42 100644 --- a/spec/controllers/build_lists_controller_spec.rb +++ b/spec/controllers/build_lists_controller_spec.rb @@ -25,7 +25,7 @@ describe BuildListsController do it "should be able to perform all action without exception" do get :all - assigns[:build_server_status].should == {} + assigns[:build_server_status].should == {} # TODO stub to isolate response.should be_success end end