client_management/lib/tasks/copy_site.rake

208 lines
12 KiB
Ruby
Raw Normal View History

2021-02-16 08:49:58 +00:00
require 'net/ssh'
require 'pathname'
namespace :create_site do
desc "Copy Site from another site"
task :copy_site,[:ip,:user,:password,:site_name,:domain_name,:port,:db_name,:path,:site_construct_id,:template_site_construct_id] => :environment do |task,args|
@password = args.password
template_site = SiteConstruct.find(args.template_site_construct_id)
if args.site_construct_id.blank?
@site_construct = SiteConstruct.new
@site_construct.server_type = (SiteServer.where(:ip=>args.ip).first.server_name rescue args.ip)
@site_construct.site_name = args.site_name
@site_construct.domain_name = args.domain_name
2021-02-21 03:59:36 +00:00
@site_construct.db_name = args.db_name.gsub(" ","")
2021-02-16 08:49:58 +00:00
@site_construct.port = args.port
@site_construct.path = args.path
@site_construct.school_name = args.site_name.split(/[-_]/)
@site_construct.user_id = User.first.id.to_s
@site_construct.save
else
@site_construct = SiteConstruct.find(args.site_construct_id)
end
begin
@site_construct.update(:status=>"creating")
@site_construct.update!(:infos=>[])
begin
Net::SSH.start(args.ip , args.user , password: args.password) do |ssh|
end
rescue Net::SSH::HostKeyMismatch
system("ssh-keygen -f \"$HOME/.ssh/known_hosts\" -R #{args.ip}")
rescue Errno::ENOTTY
system("ssh-add \"$HOME/.ssh/id_rsa\"")
end
Net::SSH.start(args.ip , args.user , password: args.password) do |ssh|
update_infos("setting nginx for #{args.site_name}")
2021-02-21 03:59:36 +00:00
nginx_setting_texts = ('upstream '+@site_construct.get_site_name+'_sock {\n'+
' server unix:'+args.path+'/'+@site_construct.get_site_name+'/tmp/unicorn.sock;\n'+
2021-02-16 08:49:58 +00:00
'}\n'+
'server {\n'+
' listen '+args.port+';\n\n'+
2021-02-21 03:59:36 +00:00
' root '+args.path+'/'+@site_construct.get_site_name+'/public;\n\n'+
2021-02-16 08:49:58 +00:00
'server_name '+args.domain_name+';\n\n'+
' client_max_body_size 500m;\n\n'+
' location / {\n'+
' try_files \$uri \$uri/index.html \$uri.html @app;\n'+
' }\n\n'+
' location @app {\n'+
' proxy_redirect off;\n'+
' proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;\n'+
' proxy_set_header Host \$http_host;\n'+
' proxy_connect_timeout 360;\n'+
2021-02-21 03:59:36 +00:00
'proxy_pass http://'+@site_construct.get_site_name+'_sock;\n'+
2021-02-16 08:49:58 +00:00
' }\n'+
'}')
2021-02-21 03:59:36 +00:00
exec_ssh_command_by_sudo_for_create(ssh,"touch /etc/nginx/orbit_sites/#{@site_construct.get_site_name}")
exec_ssh_command_by_sudo_for_create(ssh,"sh -c \"echo '#{nginx_setting_texts}' > /etc/nginx/orbit_sites/#{@site_construct.get_site_name}\"")
2021-02-16 08:49:58 +00:00
update_infos("restarting nginx")
exec_ssh_command_by_sudo_for_create(ssh,"sudo -p 'sudo password:' service nginx restart")
update_infos("finish restarting nginx")
exec_ssh_command_by_sudo_for_create(ssh,"mkdir -p #{args.path}")
update_infos("copying site's files for #{args.site_name}")
exec_ssh_command_for_create(ssh,"sudo -p 'sudo password:' apt-get install -y rsync")
if @site_construct.server_type == template_site.server_type
2021-02-21 03:59:36 +00:00
exec_ssh_command_for_create(ssh,"rsync -arv --delete --exclude={tmp/cache/,tmp/unicorn.sock,tmp/pids/*} #{template_site.path}/#{template_site.get_site_name}/ #{args.path}/#{@site_construct.get_site_name}/",true)
2021-02-16 08:49:58 +00:00
else
server = SiteServer.where(:server_name => template_site.server_type).first
exec_ssh_command_for_create(ssh,"sudo -p 'sudo password:' apt-get install -y sshpass")
2021-02-21 03:59:36 +00:00
outputs = exec_ssh_command_for_create(ssh,"sshpass -p \"#{server.password}\" rsync -arv --delete --exclude={tmp/cache/,tmp/unicorn.sock,tmp/pids/*} #{server.account}@#{server.ip}:#{template_site.path}/#{template_site.get_site_name}/ #{args.path}/#{@site_construct.get_site_name}/",true)
2021-02-16 08:49:58 +00:00
if outputs.join("\n").include?("Host key verification failed")
exec_ssh_command_by_sudo_for_create(session,"ssh-keygen -f \"$HOME/.ssh/known_hosts\" -R #{server.ip}")
exec_ssh_command_by_sudo_for_create(session,"ssh-keyscan -H #{server.ip} >> ~/.ssh/known_hosts")
2021-02-21 03:59:36 +00:00
exec_ssh_command_for_create(ssh,"sshpass -p \"#{server.password}\" rsync -arv --delete --exclude={tmp/cache/,tmp/unicorn.sock,tmp/pids/*} #{server.account}@#{server.ip}:#{template_site.path}/#{template_site.get_site_name}/ #{args.path}/#{@site_construct.get_site_name}/",true)
2021-02-16 08:49:58 +00:00
end
end
update_infos("Finish copying site's files for #{args.site_name}!")
2021-02-21 03:59:36 +00:00
exec_ssh_command_by_sudo_for_create(ssh,"sudo -p 'sudo password:' chown #{args.user}:#{args.user} #{args.path}/#{@site_construct.get_site_name} -R")
exec_ssh_command_by_sudo_for_create(ssh,"sudo -p 'sudo password:' chmod 777 #{args.path}/#{@site_construct.get_site_name} -R")
2021-02-16 08:49:58 +00:00
db_setting_text = ssh.exec!("cat #{args.path}/#{args.site_name}/config/mongoid.yml")
update_infos("setting dbname to #{args.db_name}")
2021-02-21 03:59:36 +00:00
exec_ssh_command_by_sudo_for_create(ssh,"sh -c \"echo '#{db_setting_text.gsub(template_site.db_name,args.db_name)}' > #{args.path}/#{@site_construct.get_site_name}/config/mongoid.yml\"",true)
2021-02-16 08:49:58 +00:00
update_infos("copying db from #{template_site.db_name} to #{args.db_name}")
if @site_construct.server_type == template_site.server_type
2021-02-21 03:59:36 +00:00
exec_ssh_command_by_sudo_for_create(ssh,"mongodump -d #{template_site.db_name} -o #{args.path}/#{@site_construct.get_site_name}/dump_xxxx")
exec_ssh_command_by_sudo_for_create(ssh,"mongorestore --drop -d #{args.db_name} #{args.path}/#{@site_construct.get_site_name}/dump_xxxx/#{template_site.db_name}")
exec_ssh_command_by_sudo_for_create(ssh,"rm -rf #{args.path}/#{@site_construct.get_site_name}/dump_xxxx")
2021-02-16 08:49:58 +00:00
else
exec_ssh_command_by_sudo_for_create(ssh,"sshpass -p '#{server.password}' ssh #{server.account}@#{server.ip} 'mongodump -d #{template_site.db_name} -o #{template_site.path}/#{template_site.site_name}/dump_xxxx'")
2021-02-21 03:59:36 +00:00
exec_ssh_command_for_create(ssh,"sshpass -p \"#{server.password}\" rsync -arv --delete #{server.account}@#{server.ip}:#{template_site.path}/#{template_site.get_site_name}/dump_xxxx/ #{args.path}/#{args.site_name}/dump_xxxx/")
exec_ssh_command_by_sudo_for_create(ssh,"mongorestore --drop -d #{args.db_name} #{args.path}/#{@site_construct.get_site_name}/dump_xxxx/#{template_site.db_name}")
exec_ssh_command_by_sudo_for_create(ssh,"rm -rf #{args.path}/#{@site_construct.get_site_name}/dump_xxxx")
exec_ssh_command_by_sudo_for_create(ssh,"sshpass -p '#{server.password}' ssh #{server.account}@#{server.ip} 'rm -rf #{template_site.path}/#{template_site.get_site_name}/dump_xxxx'")
2021-02-16 08:49:58 +00:00
end
update_infos("Finish copying database!")
2021-02-23 06:18:25 +00:00
update_infos("Checking extensions!")
extensions = ["downloaded_extensions.rb","built_in_extensions.rb"]
extensions.each do |extension_file|
outputs = exec_ssh_command_by_sudo_for_create(ssh,"cat #{args.path}/#{@site_construct.get_site_name}/#{extension_file}")
2021-03-09 13:31:22 +00:00
next if outputs.blank?
2021-02-23 06:18:25 +00:00
if !outputs.include?("No such file or directory")
read_lines = outputs.split("\n").map{|l| l.split('#').first}
include_path_lines = read_lines.select{|l| l.include?("path")}
include_path_lines.each do |line|
path = line.split(/[:>]/).last.gsub(/[\'\"]/,"").strip
absolute_path = (path[0] == "/") ? path : ("#{template_site.path}/#{template_site.get_site_name}/#{path}")
absolute_path = (absolute_path[-1] == "/") ? absolute_path : (absolute_path + "/")
if @site_construct.server_type == template_site.server_type
exec_ssh_command_for_create(ssh,"rsync -arv --delete #{absolute_path} #{args.path}/#{args.site_name}/#{Pathname.new(absolute_path).basename}/")
else
server = SiteServer.where(:server_name => template_site.server_type).first
exec_ssh_command_for_create(ssh,"sshpass -p \"#{server.password}\" rsync -arv --delete #{server.account}@#{server.ip}:#{absolute_path} #{args.path}/#{args.site_name}/#{Pathname.new(absolute_path).basename}/")
end
outputs = outputs.gsub(path,"#{args.path}/#{args.site_name}/#{Pathname.new(absolute_path).basename}/")
end
if include_path_lines.count != 0
2021-03-09 06:52:50 +00:00
exec_ssh_command_by_sudo_for_create(ssh,"sh -c \"echo '#{outputs.gsub("\"","\\\"").gsub("'","\\\"")}' > #{args.path}/#{@site_construct.get_site_name}/#{extension_file}\"")
2021-02-23 06:18:25 +00:00
end
end
end
update_infos("Finish checking extensions!")
2021-02-16 08:49:58 +00:00
update_infos("execing bundle install...")
2021-02-21 03:59:36 +00:00
exec_ssh_command_by_sudo_for_create(ssh,"bash -l -c 'cd #{args.path}/#{@site_construct.get_site_name}\nbundle install'",true)
exec_ssh_command_by_sudo_for_create(ssh,"bash -l -c 'cd #{args.path}/#{@site_construct.get_site_name}\nbundle install'")
2021-02-16 08:49:58 +00:00
update_infos("finish execing bundle install")
update_infos("starting #{args.site_name} web server to development")
2021-02-21 03:59:36 +00:00
outputs = exec_ssh_command_by_sudo_for_create(ssh,"bash -l -c 'cd #{args.path}/#{@site_construct.get_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 development\n'")
2021-02-16 08:49:58 +00:00
if outputs.include? "not writable"
2021-02-21 03:59:36 +00:00
exec_ssh_command_by_sudo_for_create(ssh,"sudo -p 'sudo password:' chown #{args.user}:#{args.user} #{args.path}/#{@site_construct.get_site_name} -R")
exec_ssh_command_by_sudo_for_create(ssh,"sudo -p 'sudo password:' chmod 777 #{args.path}/#{@site_construct.get_site_name} -R")
2021-02-16 08:49:58 +00:00
end
update_infos("finish creating #{args.site_name}")
2021-02-21 03:59:36 +00:00
exec_ssh_command_by_sudo_for_create(ssh,"chmod 777 #{args.path}/#{@site_construct.get_site_name} -R")
2021-02-16 08:49:58 +00:00
@site_construct.update(:status =>"finish")
puts "finish creating #{args.site_name} on #{args.ip}"
end
rescue =>e
@site_construct.update(:status =>"error",:infos=>@site_construct.infos.push("#{e}"))
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_for_exec(info,update_last=false)
if update_last
@thread.status["infos"][-1] += info
else
@thread.status["infos"] = @thread.status["infos"].push(info)
end
@thread.save!
return @thread.status["infos"]
end
def exec_ssh_command_for_create(session,command,update=false)
outputs = []
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|
outputs.push(data)
print "#{data}"
if update
if data.include? "\n"
update_infos_for_exec(data)
else
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
end
end
end
session.loop
return outputs
end
def exec_ssh_command_by_sudo_for_create(session,command,update=false)
outputs = exec_ssh_command_for_create(session,command,update)
if outputs.join("\n").include?("Permission denied") || outputs.join("\n").include?("Operation not permitted")
outputs = exec_ssh_command_for_create(session,"sudo -p 'sudo password:' #{command}",update)
end
return outputs.join("\n")
end
def update_infos_for_exec(info,update_last=false)
if update_last && !@site_construct.infos.empty?
@site_construct.infos[-1] += info
else
@site_construct.infos = @site_construct.infos.push(info)
end
@site_construct.save!
return @site_construct.infos
end
def update_infos(info)
puts info
@site_construct.infos = @site_construct.infos.push(info)
@site_construct.save!
return @site_construct.infos
end
end