182 lines
9.2 KiB
Ruby
182 lines
9.2 KiB
Ruby
require 'net/ssh'
|
|
require 'pathname'
|
|
namespace :exec_commands do
|
|
desc "Exec commands Script"
|
|
task :exec_commands,[:site_construct_id,:commands,:type,:server_name] => :environment do |task,args|
|
|
@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']
|
|
rails_env = default_rails_env
|
|
log_files = exec_ssh_command_by_sudo_and_see_output(ssh,"ls -t '#{@site_construct.path}/#{@site_construct.site_name}/log'",false).flat_map{|output| output.split(/(\r\n|\t|\n|\s+)/)}.select{|output| output.present? && /(\r\n|\t|\n|\s+)/.match(output).nil?} rescue []
|
|
log_files.each do |log_file|
|
|
if( enable_rails_env.include?(log_file.sub('.log','')) rescue false)
|
|
rails_env = log_file.sub('.log','')
|
|
break
|
|
end
|
|
end
|
|
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}\nkill -s TERM `fuser tmp/unicorn.sock`\nsudo -p \"sudo password:\" kill -s TERM `sudo -p \"sudo password:\" fuser tmp/unicorn.sock`\nsudo -p \"sudo password:\" rm -f tmp/pids/unicorn.pid\nbundle 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
|
|
end
|
|
end
|
|
update_infos_for_exec("finish starting #{@site_construct.site_name}")
|
|
@site_construct.update(:status =>"finish")
|
|
elsif args.type == 'exec_all'
|
|
sites = SiteConstruct.where(:server_type=>args.server_name).to_a
|
|
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
|
|
end
|
|
else
|
|
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
|
|
end
|
|
end
|
|
end
|
|
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
|
|
end
|
|
end
|
|
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
|
|
def update_infos_for_exec(info,update_last=false)
|
|
if update_last && !@site_construct.infos.empty?
|
|
@site_construct.infos[-1] += info.to_s
|
|
else
|
|
@site_construct.infos = @site_construct.infos.push(info.to_s)
|
|
end
|
|
@site_construct.save!
|
|
return @site_construct.infos
|
|
end
|
|
def update_thread_infos_for_exec(info,update_last=false)
|
|
if update_last && !@thread.status["infos"].empty?
|
|
@thread.status["infos"][-1] += info.to_s
|
|
else
|
|
@thread.status["infos"] = @thread.status["infos"].push(info.to_s)
|
|
end
|
|
@thread.save!
|
|
return @thread.status["infos"]
|
|
end
|
|
def exec_ssh_command_and_see_output(session,command,update=true)
|
|
outputs = []
|
|
@flag = (@type == "exec_all")
|
|
if update
|
|
update_thread_infos_for_exec("execing #{command} on on <a href='#{((@site_construct.port == "443") ? "https" : "http")}://#{@site_construct.domain_name}#{((@site_construct.port=="80" || @site_construct.port=="443") ? "" : (':'+@site_construct.port))}'>#{@site_construct.domain_name}</a>") if @flag
|
|
update_infos_for_exec("execing #{command}")
|
|
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|
|
|
print "#{data}"
|
|
if data.include? "\n" || outputs.empty?
|
|
outputs.push(data.to_s)
|
|
if update
|
|
update_thread_infos_for_exec(data) if @flag
|
|
update_infos_for_exec(data)
|
|
end
|
|
else
|
|
outputs[-1] += data.to_s rescue ""
|
|
if update
|
|
update_thread_infos_for_exec(data,true) if @flag
|
|
update_infos_for_exec(data,true)
|
|
end
|
|
end
|
|
if data.to_s.include?("sudo password:") || data.to_s.include?("Password:")
|
|
channel.send_data "#{@password}\n"
|
|
end
|
|
end
|
|
channel.on_close do |ch|
|
|
if update
|
|
update_thread_infos_for_exec("finish execing #{command} on <a href='#{((@site_construct.port == "443") ? "https" : "http")}://#{@site_construct.domain_name}#{((@site_construct.port=="80" || @site_construct.port=="443") ? "" : (':'+@site_construct.port))}'>#{@site_construct.domain_name}</a>") if @flag
|
|
update_infos_for_exec("finish execing #{command}")
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
session.loop
|
|
return outputs
|
|
end
|
|
def exec_ssh_command_by_sudo_and_see_output(session,command,update=true)
|
|
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
|
|
return outputs
|
|
end
|
|
end |