client_management/lib/tasks/detect_sites.rake

117 lines
7.3 KiB
Ruby

require 'net/ssh'
require 'pathname'
namespace :create_site do
desc "Detect sites"
task :detect_sites,[:detect_name] => :environment do |task,args|
#Multithread.where(:key=>'detect_sites').destroy
Multithread.where(:key=>'detect_sites').each{|thread| thread.destroy if (thread.status["status"] == "error" || thread.status["status"] == "finish")}
@thread = Multithread.where(:key=>'detect_sites').first
if @thread.nil?
begin
@thread = Multithread.create(:key=>'detect_sites',:status=>{"infos"=>[],"status"=>"detecting"})
if( args.detect_name.nil? rescue true)
site_servers = SiteServer.all.to_a
else
site_servers = SiteServer.where(:server_name=>args.detect_name).to_a
end
site_servers.each do |site_server|
@site_server = site_server
update_thread_infos("<span style='color: skyblue;'>"+@site_server.server_name+"</span>")
@password = @site_server.password
begin
begin
Net::SSH.start(@site_server.ip , @site_server.account , password: @site_server.password) do |ssh|
end
rescue Net::SSH::HostKeyMismatch
system("ssh-keygen -f \"$HOME/.ssh/known_hosts\" -R #{@site_server.ip}")
rescue Errno::ENOTTY
system("ssh-add \"$HOME/.ssh/id_rsa\"")
rescue => e
update_thread_infos(e.to_s)
next
end
Net::SSH.start(@site_server.ip , @site_server.account , password: @site_server.password) do |ssh|
nginx_include_dir = exec_command_by_user(ssh,'grep include /etc/nginx/nginx.conf | grep -v "\#\|include /etc/nginx/mime.types\|include /etc/nginx/conf.d/\*.conf\|/etc/nginx/sites-enabled/\*"')
nginx_include_dir = nginx_include_dir.gsub(/include|;|\n/,'').strip
domain_name = @site_server.domain_name#'serv.rulingcom.com'
server_names = exec_command_by_user(ssh,"grep 'server_name' -r #{nginx_include_dir}")
server_names_array = server_names.scan(/(.*):[ \t]*server_name[ \t]+(.*);/)
server_names_array = server_names_array.group_by{|v| v[0]}
server_names_array.each do |nginx_file, server_name_with_file|
server_names_for_site = server_name_with_file.map{|v| v[1].split(/[ |\t]+/)}.flatten.uniq - ["localhost","127.0.0.1"]
server_name_list = []
server_names_for_site.each do |server_name_for_site|
if !server_name_for_site.include?(domain_name)
next if !`nslookup "#{server_name_for_site}"`.include?(@site_server.ip)
end
server_name_list << server_name_for_site
end
server_name = server_name_list.join(' ')
site_path = Pathname.new(exec_ssh_command_by_sudo(ssh,"echo `grep root #{nginx_file} | grep -v -e '#.*root'`").to_s.split("\n").first.to_s.strip.split("root").last.to_s.gsub(";","").strip).dirname.to_s
if site_path.present? && exec_ssh_command_by_sudo(ssh,"ls #{site_path}").split.length != 0 && exec_ssh_command_by_sudo(ssh,"ls #{site_path}/Gemfile").include?("No such file or directory")
SiteConstruct.where(:server_type => @site_server.server_name , :domain_name=>server_name).destroy
next
end
path = Pathname.new(site_path).dirname.to_s
site_name = Pathname.new(site_path).basename.to_s
server_type = @site_server.server_name
port = exec_ssh_command_by_sudo(ssh,"echo `grep 'listen' #{nginx_file} | grep -v -e '#.*listen'`").split("\n").first.strip.split("listen").last.strip.split(";").first.split.select{|p| p.strip == p.strip.to_i.to_s}.first.strip rescue "80"
db_name = exec_ssh_command_by_sudo(ssh,"echo `cat #{site_path}/config/mongoid.yml | grep 'database'`").split("database:").last.strip
db_name = site_name.gsub("-","_") if db_name.include?("No such file or directory")
unicorn_sock_path = exec_ssh_command_by_sudo(ssh,"echo `grep 'server unix' #{nginx_file} | grep -v -e '#.*server unix'`").strip.split("server unix").last.strip.split(":").last.strip rescue (site_path+"/tmp/unicorn.sock")
if Pathname.new(path).basename.to_s == "orbit_sites" || Pathname.new(path).basename.to_s == "housing_sites" || Pathname.new(path).basename.to_s == "dev_sites" || Pathname.new(path).dirname.to_s == "/home"
school_name = nil
site_type = "Gravity"
else
school_name = Pathname.new(path).basename.to_s
site_type = "School"
end
pid_infos = exec_ssh_command_by_sudo(ssh,"fuser #{unicorn_sock_path}").to_s.strip.gsub("\n","")
if pid_infos.length != 0 && !pid_infos.include?("not exist") && !pid_infos.include?("No such file or directory")
status = "finish"
else
bundle_show_info = exec_ssh_command_by_sudo(ssh,"bash -l -c 'cd #{site_path};bundle show'")
if bundle_show_info.include?("is not yet checked out") || bundle_show_info.include?("No such file or directory")
status = ""
else
status = "closed"
end
end
site_constructs = SiteConstruct.where(:server_type => server_type , :domain_name.in => [server_name,*server_name_list]).to_a
site_construct = site_constructs[0]
Array(site_constructs[1..-1]).each do |s|
s.destroy
end
update_thread_infos("Detect <a href='#{((port == "443") ? "https" : "http")}://#{server_name}#{((port=="80" || port=="443") ? "" : (':'+port))}'>#{server_name}</a>".html_safe)
if site_construct.nil?
site_construct = SiteConstruct.create(:server_type=>server_type,:site_name=>site_name,:domain_name=>server_name,:nginx_file=>nginx_file,:db_name=>db_name,:port=>port,:path=>path,:site_type=>site_type,:school_name=>school_name,:user_id=>User.first.id,:status=>status)
else
site_construct.update(:server_type=>server_type,:site_name=>site_name,:domain_name=>server_name,:nginx_file=>nginx_file,:db_name=>db_name,:port=>port,:path=>path,:site_type=>site_type,:school_name=>school_name,:user_id=>User.first.id,:status=>status)
end
end
end
end
end
SiteConstruct.where(:domain_name.in => [nil,'','localhost','127.0.0.1']).destroy
@thread.update(:status=>@thread.status.merge({"status"=>"finish"}))
rescue => e
puts [e,e.backtrace]
@thread.update(:status=>{"infos"=>@thread.status["infos"].push(e.to_s),"status"=>"error"})
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_thread_infos(info)
puts info
@thread.status["infos"] = @thread.status["infos"].push(info)
@thread.save!
return @thread.status["infos"]
end
end