2020-04-28 13:26:49 +00:00
require 'net/ssh'
require 'pathname'
2021-01-19 04:48:03 +00:00
namespace :exec_commands do
desc " Exec commands Script "
2021-03-17 11:19:18 +00:00
task :exec_commands , [ :site_construct_id , :commands , :type , :server_name , :rails_env ] = > :environment do | task , args |
2021-01-19 04:48:03 +00:00
@type = args . type
if ! args . site_construct_id . blank?
@site_construct = SiteConstruct . find ( args . site_construct_id )
site_server = SiteServer . where ( :server_name = > @site_construct . server_type ) . first
site_servers = [ site_server ]
else
@site_construct = nil
site_servers = SiteServer . where ( :server_name . in = > args . server_name . split ( " //// " ) ) . to_a
end
if args . type == " exec_all "
Multithread . where ( :key = > 'execing_commands' ) . each { | thread | thread . destroy if ( thread . status [ " status " ] == " error " || thread . status [ " status " ] == " finish " ) }
@thread = Multithread . where ( :key = > 'execing_commands' ) . first
else
@thread = nil
end
if @thread . nil?
begin
if @thread . nil? && args . type == " exec_all "
@thread = Multithread . create ( :key = > 'execing_commands' , :status = > { " infos " = > [ ] , " status " = > " execing " } )
end
site_servers . each do | site_server |
ip = site_server . ip
user = site_server . account
password = site_server . password
@password = password
begin
Net :: SSH . start ( ip , user , password : password ) do | ssh |
end
rescue Net :: SSH :: HostKeyMismatch
system ( " ssh-keygen -f \" $HOME/.ssh/known_hosts \" -R #{ ip } " )
rescue Errno :: ENOTTY
system ( " ssh-add \" $HOME/.ssh/id_rsa \" " )
end
Net :: SSH . start ( ip , user , password : password ) do | ssh |
@site_construct . update! ( :infos = > [ ] ) rescue nil
if args . type == 'close_site'
exec_ssh_command_by_sudo_and_see_output ( ssh , " chmod 777 #{ @site_construct . path } / #{ @site_construct . site_name } -R " , false )
exec_ssh_command_by_sudo_and_see_output ( ssh , " bash -l -c 'kill -s TERM `fuser #{ @site_construct . path } / #{ @site_construct . site_name } /tmp/unicorn.sock`' " , false )
update_infos_for_exec ( " finish closing #{ @site_construct . site_name } " )
@site_construct . update ( :status = > " closed " )
elsif args . type == 'open_site'
default_rails_env = 'development'
enable_rails_env = [ 'development' , 'production' ]
2021-12-17 01:36:01 +00:00
rails_env = @site_construct . rails_env . blank? ? default_rails_env : @site_construct . rails_env
2021-04-14 10:55:07 +00:00
cmd_output = exec_ssh_command_by_sudo_and_see_output ( ssh , " ps -o args= -p `cat #{ @site_construct . path } / #{ @site_construct . site_name } /tmp/pids/unicorn.pid` " , false ) rescue [ ]
enable_rails_env . each do | env |
if ( cmd_output [ 0 ] . include? ( env ) rescue false )
rails_env = env
break
elsif ( cmd_output [ 0 ] . include? ( " No such file or directory " ) rescue false )
2021-12-17 01:36:01 +00:00
@site_construct . update ( :status = > " closed " )
2021-01-19 04:48:03 +00:00
break
end
end
2021-03-17 11:19:18 +00:00
if args . rails_env . present?
rails_env = args . rails_env
end
2021-04-14 11:57:06 +00:00
@site_construct . update ( :rails_env = > rails_env )
2021-01-19 04:48:03 +00:00
update_infos_for_exec ( " starting site to #{ rails_env } " )
outputs = exec_ssh_command_by_sudo_and_see_output ( ssh , " sudo -p 'sudo password:' chmod 777 #{ @site_construct . path } / #{ @site_construct . site_name } -R " , false )
output = exec_ssh_command_by_sudo_and_see_output ( ssh , " bash -l -c 'cd #{ @site_construct . path } / #{ @site_construct . site_name } \n kill -s TERM `fuser tmp/unicorn.sock` \n sudo -p \" sudo password: \" kill -s TERM `sudo -p \" sudo password: \" fuser tmp/unicorn.sock` \n sudo -p \" sudo password: \" rm -f tmp/pids/unicorn.pid \n bundle exec unicorn_rails -c config/unicorn.rb -D -E #{ rails_env } \n ' " , false )
if output . include? " bundle install "
update_infos_for_exec ( " not yet bundle install " )
outputs = exec_ssh_command_by_sudo_and_see_output ( ssh , " bash -l -c 'cd #{ @site_construct . path } / #{ @site_construct . site_name } ;bundle install' " )
if outputs . join ( " \n " ) . include? " Username for "
update_infos_for_exec ( " Cannot finish bundle install. " )
update_infos_for_exec ( " This site include an private git project. " )
@site_construct . update ( :status = > " error " )
break
2021-12-17 01:36:01 +00:00
else
exec_ssh_command_by_sudo_and_see_output ( ssh , " bundle exec unicorn_rails -c config/unicorn.rb -D -E #{ rails_env } " , false )
2021-01-19 04:48:03 +00:00
end
end
update_infos_for_exec ( " finish starting #{ @site_construct . site_name } " )
@site_construct . update ( :status = > " finish " )
elsif args . type == 'exec_all'
2021-04-01 09:53:05 +00:00
sites = SiteConstruct . where ( :server_type = > site_server . server_name ) . to_a
2021-01-19 04:48:03 +00:00
commands = args . commands . split ( " //// " ) . select { | c | c != " " } rescue [ args . commands ]
sites . each do | site_construct |
@site_construct = site_construct
@site_construct . update! ( :infos = > [ ] )
exec_ssh_command_by_sudo ( ssh , " chmod 777 #{ @site_construct . path } / #{ @site_construct . site_name } -R " )
commands . each do | command |
exec_ssh_command_by_sudo_and_see_output ( ssh , " bash -l -c 'cd #{ @site_construct . path } / #{ @site_construct . site_name } ; #{ command } ' " )
end
2020-04-28 13:26:49 +00:00
end
else
2021-01-19 04:48:03 +00:00
exec_ssh_command_by_sudo ( ssh , " chmod 777 #{ @site_construct . path } / #{ @site_construct . site_name } -R " )
commands = args . commands . split ( " //// " ) . select { | c | c != " " } rescue [ args . commands ]
commands . each do | command |
exec_ssh_command_by_sudo_and_see_output ( ssh , " bash -l -c 'cd #{ @site_construct . path } / #{ @site_construct . site_name } ; #{ command } ' " )
end
2020-04-28 13:26:49 +00:00
end
end
end
2021-01-19 04:48:03 +00:00
if ! @thread . nil?
@thread . update ( :status = > @thread . status . merge ( { " status " = > " finish " } ) )
end
rescue = > e
if ! @thread . nil?
@thread . update ( :status = > { " infos " = > @thread . status [ " infos " ] . push ( e . message ) , " status " = > " error " } )
@thread . update ( :status = > { " infos " = > @thread . status [ " infos " ] . push ( e . backtrace . join ( " \n " ) ) , " status " = > " error " } )
end
if ! @site_construct . nil?
@site_construct . update ( :status = > " error " , :infos = > @site_construct . infos . push ( " #{ e . message } " ) )
@site_construct . update ( :status = > " error " , :infos = > @site_construct . infos . push ( " #{ e . backtrace . join ( " \n " ) } " ) )
end
2020-04-28 13:26:49 +00:00
end
2021-01-19 04:48:03 +00:00
end
2020-04-28 13:26:49 +00:00
end
def exec_ssh_command_by_sudo ( session , command )
output = session . exec! ( " echo ' #{ @password } ' | sudo -S #{ command } " )
# output = session.exec!("echo '#{@password}' | sudo -S -s #{command}")
if output . include? ( " sudo: " ) && output . include? ( " command not found " )
output = session . exec! ( command )
end
return output
end
2021-08-11 10:25:03 +00:00
def update_infos_for_exec ( info , update_last = false , update_array = false )
2021-08-11 08:16:14 +00:00
return if @site_construct . nil?
2021-01-19 04:48:03 +00:00
if update_last && ! @site_construct . infos . empty?
@site_construct . infos [ - 1 ] += info . to_s
else
2021-08-11 10:25:03 +00:00
if update_array
@site_construct . infos += info
else
@site_construct . infos . push ( info . to_s )
end
2021-01-19 04:48:03 +00:00
end
2020-04-28 13:26:49 +00:00
@site_construct . save!
return @site_construct . infos
end
2021-08-11 10:25:03 +00:00
def update_thread_infos_for_exec ( info , update_last = false , update_array = false )
2021-01-19 04:48:03 +00:00
if update_last && ! @thread . status [ " infos " ] . empty?
@thread . status [ " infos " ] [ - 1 ] += info . to_s
else
2021-08-11 10:25:03 +00:00
if update_array
@thread . status [ " infos " ] += info
else
@thread . status [ " infos " ] . push ( info . to_s )
end
2021-01-19 04:48:03 +00:00
end
@thread . save!
return @thread . status [ " infos " ]
end
2021-08-11 08:16:14 +00:00
def exec_ssh_command_and_see_output ( session , command , update = true , output_string = false )
2021-01-19 04:48:03 +00:00
outputs = [ ]
@flag = ( @type == " exec_all " )
if update
2021-08-11 08:16:14 +00:00
if @site_construct
update_thread_infos_for_exec ( " execing #{ command } on on <a href=' #{ ( ( @site_construct . get_port == " 443 " ) ? " https " : " http " ) } :// #{ @site_construct . domain_name } #{ ( ( @site_construct . get_port == " 80 " || @site_construct . get_port == " 443 " || @site_construct . get_port . blank? ) ? " " : ( ':' + @site_construct . get_port ) ) } '> #{ @site_construct . domain_name } </a> " ) if @flag
update_infos_for_exec ( " execing #{ command } " )
elsif @thread
update_thread_infos_for_exec ( " execing #{ command } ... " )
end
2021-01-19 04:48:03 +00:00
end
session . open_channel do | channel |
channel . request_pty do | channel , success |
channel . exec ( command ) do | ch , success |
abort " could not execute command: #{ command } " unless success
channel . on_data do | ch , data |
2021-08-11 10:25:03 +00:00
if data . to_s . include? ( " sudo password: " ) || data . to_s . include? ( " Password: " )
channel . send_data " #{ @password } \n "
2021-01-19 04:48:03 +00:00
else
2021-08-11 10:25:03 +00:00
print " #{ data } "
2021-12-01 12:59:18 +00:00
data_str = data . to_s
2021-08-11 10:25:03 +00:00
if data . include? ( " \n " ) || outputs . empty?
2021-12-01 12:59:18 +00:00
output_lines = data_str . split ( " \n " )
2021-12-01 13:11:18 +00:00
first_output = output_lines [ 0 ]
2021-12-01 12:59:18 +00:00
if outputs . count != 0
outputs [ - 1 ] += first_output
2021-12-01 13:11:18 +00:00
else
outputs << first_output
2021-12-01 12:59:18 +00:00
end
new_arr = output_lines [ 1 .. - 1 ]
if data_str [ - 1 ] == " \n "
new_arr << " "
end
outputs += new_arr
2021-08-11 10:25:03 +00:00
if update
2021-12-01 12:59:18 +00:00
if first_output
update_thread_infos_for_exec ( first_output , true ) if @flag
update_infos_for_exec ( first_output , true )
end
update_thread_infos_for_exec ( new_arr , false , true ) if @flag
update_infos_for_exec ( new_arr , false , true )
2021-08-11 10:25:03 +00:00
end
2021-05-31 09:58:24 +00:00
else
2021-08-11 10:25:03 +00:00
if outputs . count == 0
2021-12-01 12:59:18 +00:00
outputs . push ( data_str )
2021-08-11 10:25:03 +00:00
else
2021-12-01 12:59:18 +00:00
outputs [ - 1 ] += ( data_str rescue " " )
2021-08-11 10:25:03 +00:00
end
if update
2021-12-01 12:59:18 +00:00
update_thread_infos_for_exec ( data_str , true ) if @flag
update_infos_for_exec ( data_str , true )
2021-08-11 10:25:03 +00:00
end
2021-01-19 04:48:03 +00:00
end
end
end
channel . on_close do | ch |
if update
2021-08-11 08:16:14 +00:00
if @site_construct
update_thread_infos_for_exec ( " finish execing #{ command } on <a href=' #{ ( ( @site_construct . get_port == " 443 " ) ? " https " : " http " ) } :// #{ @site_construct . domain_name } #{ ( ( @site_construct . get_port == " 80 " || @site_construct . get_port == " 443 " || @site_construct . get_port . blank? ) ? " " : ( ':' + @site_construct . get_port ) ) } '> #{ @site_construct . domain_name } </a> " ) if @flag
update_infos_for_exec ( " finish execing #{ command } " )
elsif @thread
update_thread_infos_for_exec ( " finish execing #{ command } " )
end
2021-01-19 04:48:03 +00:00
end
end
end
end
end
session . loop
2021-08-11 08:16:14 +00:00
if output_string
return outputs . join ( " \n " )
else
return outputs
end
2021-01-19 04:48:03 +00:00
end
2021-08-11 08:16:14 +00:00
def exec_ssh_command_by_sudo_and_see_output ( session , command , update = true , output_string = false )
2021-01-19 04:48:03 +00:00
outputs = exec_ssh_command_and_see_output ( session , command , update )
if outputs . join ( " \n " ) . include? ( " Permission denied " ) || outputs . join ( " \n " ) . include? ( " Operation not permitted " )
outputs = exec_ssh_command_and_see_output ( session , " sudo -p 'sudo password:' #{ command } " , update )
end
2021-08-11 08:16:14 +00:00
if output_string
return outputs . join ( " \n " )
else
return outputs
end
2021-01-19 04:48:03 +00:00
end
2020-04-28 13:26:49 +00:00
end