Add copy site feature.
This commit is contained in:
parent
481ff945a0
commit
9a6ebf3b65
|
@ -83,9 +83,15 @@ class Admin::SitePanelController < OrbitAdminController
|
||||||
db_name = site_construct.db_name
|
db_name = site_construct.db_name
|
||||||
path = site_construct.path
|
path = site_construct.path
|
||||||
site_construct_id = site_construct.id.to_s
|
site_construct_id = site_construct.id.to_s
|
||||||
|
if params[:site_construct][:copy_id].blank?
|
||||||
Thread.new do
|
Thread.new do
|
||||||
system("rake create_site:create_site['#{git_template_url}','#{git_extension_url}','#{git_url}','#{ip}','#{user}','#{password}','#{site_name}','#{domain_name}','#{port}','#{db_name}','#{path}','#{site_construct_id}']")
|
system("rake create_site:create_site['#{git_template_url}','#{git_extension_url}','#{git_url}','#{ip}','#{user}','#{password}','#{site_name}','#{domain_name}','#{port}','#{db_name}','#{path}','#{site_construct_id}']")
|
||||||
end
|
end
|
||||||
|
else
|
||||||
|
Thread.new do
|
||||||
|
system("rake create_site:copy_site['#{ip}','#{user}','#{password}','#{site_name}','#{domain_name}','#{port}','#{db_name}','#{path}','#{site_construct_id}','#{params[:site_construct][:copy_id]}']")
|
||||||
|
end
|
||||||
|
end
|
||||||
redirect_to "#{admin_site_panel_sites_list_path}?id=#{site_construct_id}"
|
redirect_to "#{admin_site_panel_sites_list_path}?id=#{site_construct_id}"
|
||||||
end
|
end
|
||||||
def create_site
|
def create_site
|
||||||
|
@ -162,7 +168,9 @@ class Admin::SitePanelController < OrbitAdminController
|
||||||
private
|
private
|
||||||
|
|
||||||
def site_construct_params
|
def site_construct_params
|
||||||
params.require(:site_construct).permit!
|
site_construct_params = params.require(:site_construct).permit!
|
||||||
|
site_construct_params = site_construct_params.except(:copy_id)
|
||||||
|
return site_construct_params
|
||||||
end
|
end
|
||||||
def site_server_params
|
def site_server_params
|
||||||
params.require(:site_server).permit!
|
params.require(:site_server).permit!
|
||||||
|
|
|
@ -38,4 +38,17 @@ class SiteConstruct
|
||||||
record.path = "/home/rulingcom/#{dir_path}"
|
record.path = "/home/rulingcom/#{dir_path}"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
def get_domain_name
|
||||||
|
scheme = ""
|
||||||
|
extra_port = ""
|
||||||
|
if self.port == "443"
|
||||||
|
scheme = "https://"
|
||||||
|
else
|
||||||
|
scheme = "http://"
|
||||||
|
if self.port != "80"
|
||||||
|
extra_port = ":#{self.port}"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return (scheme + self.domain_name + extra_port)
|
||||||
|
end
|
||||||
end
|
end
|
|
@ -20,6 +20,16 @@
|
||||||
<div class="tab-content module-area">
|
<div class="tab-content module-area">
|
||||||
<!-- Basic Module -->
|
<!-- Basic Module -->
|
||||||
<div class="tab-pane fade in active" id="basic">
|
<div class="tab-pane fade in active" id="basic">
|
||||||
|
<div class="control-group">
|
||||||
|
<% copy_source = SiteConstruct.find(params[:copy_id]) rescue nil %>
|
||||||
|
<% if copy_source %>
|
||||||
|
<label class="control-label muted"><%= t("client_management.copy_source") %></label>
|
||||||
|
<div class="controls">
|
||||||
|
<a title="<%= copy_source.site_name %>" href="<%= copy_source.get_domain_name %>" style="font-weight: bold; font-size: 1.3em;"><%= copy_source.site_name %></a>
|
||||||
|
</div>
|
||||||
|
<%= f.hidden_field :copy_id, :value => params[:copy_id] %>
|
||||||
|
<% end %>
|
||||||
|
</div>
|
||||||
<div class="control-group">
|
<div class="control-group">
|
||||||
<%= f.label :server_type ,"Server", :class => "control-label muted" %>
|
<%= f.label :server_type ,"Server", :class => "control-label muted" %>
|
||||||
<div class="controls">
|
<div class="controls">
|
||||||
|
|
|
@ -30,7 +30,10 @@
|
||||||
<% end%>
|
<% end%>
|
||||||
<a href="#" title="Exec commands on <%=site.domain_name%>" class="btn btn-primary exec_commands" data-id="<%=site.id.to_s%>">Exec commands</a>
|
<a href="#" title="Exec commands on <%=site.domain_name%>" class="btn btn-primary exec_commands" data-id="<%=site.id.to_s%>">Exec commands</a>
|
||||||
<a href="<%=admin_site_panel_edit_site_path+"?id=#{site.id}&type=detail"%>" title="See <%=site.domain_name%> detail" class="btn btn-primary see_detail" data-id="<%=site.id.to_s%>">Detail</a>
|
<a href="<%=admin_site_panel_edit_site_path+"?id=#{site.id}&type=detail"%>" title="See <%=site.domain_name%> detail" class="btn btn-primary see_detail" data-id="<%=site.id.to_s%>">Detail</a>
|
||||||
<a href="<%=admin_site_panel_edit_site_path+"?id=#{site.id}&type=delete_from_list"%>" title="Delete <%=site.domain_name%> from list" class="btn btn-primary see_detail" data-id="<%=site.id.to_s%>">Delete from list</a>
|
<a href="<%=admin_site_panel_edit_site_path+"?id=#{site.id}&type=delete_from_list"%>" title="Delete <%=site.domain_name%> from list" class="btn btn-primary" data-id="<%=site.id.to_s%>">Delete from list</a>
|
||||||
|
<% if site.status == "finish" || site.status == "closed" %>
|
||||||
|
<a href="<%=admin_site_panel_path+"?copy_id=#{site.id}"%>" title="Copy site to another site." class="btn btn-primary">Copy site</a>
|
||||||
|
<% end %>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<% end %>
|
<% end %>
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
en:
|
en:
|
||||||
client_management:
|
client_management:
|
||||||
|
copy_source: Copy Source
|
||||||
see_sites: See sites on the server
|
see_sites: See sites on the server
|
||||||
client_management: Client Management
|
client_management: Client Management
|
||||||
my_sites: My Sites
|
my_sites: My Sites
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
zh_tw:
|
zh_tw:
|
||||||
client_management:
|
client_management:
|
||||||
|
copy_source: 複製來源
|
||||||
see_sites: 查看主機上的網站
|
see_sites: 查看主機上的網站
|
||||||
client_management: Client Management
|
client_management: Client Management
|
||||||
my_sites: My Sites
|
my_sites: My Sites
|
||||||
|
|
|
@ -0,0 +1,181 @@
|
||||||
|
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
|
||||||
|
@site_construct.db_name = args.db_name
|
||||||
|
@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}")
|
||||||
|
nginx_setting_texts = ('upstream '+args.site_name+'_sock {\n'+
|
||||||
|
' server unix:'+args.path+'/'+args.site_name+'/tmp/unicorn.sock;\n'+
|
||||||
|
'}\n'+
|
||||||
|
'server {\n'+
|
||||||
|
' listen '+args.port+';\n\n'+
|
||||||
|
' root '+args.path+'/'+args.site_name+'/public;\n\n'+
|
||||||
|
'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'+
|
||||||
|
'proxy_pass http://'+args.site_name+'_sock;\n'+
|
||||||
|
' }\n'+
|
||||||
|
'}')
|
||||||
|
exec_ssh_command_by_sudo_for_create(ssh,"touch /etc/nginx/orbit_sites/#{args.site_name}")
|
||||||
|
exec_ssh_command_by_sudo_for_create(ssh,"sh -c \"echo '#{nginx_setting_texts}' > /etc/nginx/orbit_sites/#{args.site_name}\"")
|
||||||
|
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
|
||||||
|
exec_ssh_command_for_create(ssh,"rsync -arv --delete --exclude={tmp/cache/,tmp/unicorn.sock,tmp/pids/*} #{template_site.path}/#{template_site.site_name}/ #{args.path}/#{args.site_name}/",true)
|
||||||
|
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")
|
||||||
|
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.site_name}/ #{args.path}/#{args.site_name}/",true)
|
||||||
|
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")
|
||||||
|
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.site_name}/ #{args.path}/#{args.site_name}/",true)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
update_infos("Finish copying site's files for #{args.site_name}!")
|
||||||
|
|
||||||
|
exec_ssh_command_by_sudo_for_create(ssh,"sudo -p 'sudo password:' chown #{args.user}:#{args.user} #{args.path}/#{args.site_name} -R")
|
||||||
|
exec_ssh_command_by_sudo_for_create(ssh,"sudo -p 'sudo password:' chmod 777 #{args.path}/#{args.site_name} -R")
|
||||||
|
db_setting_text = ssh.exec!("cat #{args.path}/#{args.site_name}/config/mongoid.yml")
|
||||||
|
update_infos("setting dbname to #{args.db_name}")
|
||||||
|
exec_ssh_command_by_sudo_for_create(ssh,"sh -c \"echo '#{db_setting_text.gsub(template_site.db_name,args.db_name)}' > #{args.path}/#{args.site_name}/config/mongoid.yml\"",true)
|
||||||
|
|
||||||
|
update_infos("copying db from #{template_site.db_name} to #{args.db_name}")
|
||||||
|
if @site_construct.server_type == template_site.server_type
|
||||||
|
exec_ssh_command_by_sudo_for_create(ssh,"mongodump -d #{template_site.db_name} -o #{args.path}/#{args.site_name}/dump_xxxx")
|
||||||
|
exec_ssh_command_by_sudo_for_create(ssh,"mongorestore --drop -d #{args.db_name} #{args.path}/#{args.site_name}/dump_xxxx/#{template_site.db_name}")
|
||||||
|
exec_ssh_command_by_sudo_for_create(ssh,"rm -rf #{args.path}/#{args.site_name}/dump_xxxx")
|
||||||
|
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'")
|
||||||
|
exec_ssh_command_for_create(ssh,"sshpass -p \"#{server.password}\" rsync -arv --delete #{server.account}@#{server.ip}:#{template_site.path}/#{template_site.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}/#{args.site_name}/dump_xxxx/#{template_site.db_name}")
|
||||||
|
exec_ssh_command_by_sudo_for_create(ssh,"rm -rf #{args.path}/#{args.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.site_name}/dump_xxxx'")
|
||||||
|
end
|
||||||
|
update_infos("Finish copying database!")
|
||||||
|
|
||||||
|
update_infos("execing bundle install...")
|
||||||
|
exec_ssh_command_by_sudo_for_create(ssh,"bash -l -c 'cd #{args.path}/#{args.site_name}\nbundle install'",true)
|
||||||
|
exec_ssh_command_by_sudo_for_create(ssh,"bash -l -c 'cd #{args.path}/#{args.site_name}\nbundle install'")
|
||||||
|
update_infos("finish execing bundle install")
|
||||||
|
update_infos("starting #{args.site_name} web server to development")
|
||||||
|
outputs = exec_ssh_command_by_sudo_for_create(ssh,"bash -l -c 'cd #{args.path}/#{args.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'")
|
||||||
|
if outputs.include? "not writable"
|
||||||
|
exec_ssh_command_by_sudo_for_create(ssh,"sudo -p 'sudo password:' chown #{args.user}:#{args.user} #{args.path}/#{args.site_name} -R")
|
||||||
|
exec_ssh_command_by_sudo_for_create(ssh,"sudo -p 'sudo password:' chmod 777 #{args.path}/#{args.site_name} -R")
|
||||||
|
end
|
||||||
|
update_infos("finish creating #{args.site_name}")
|
||||||
|
exec_ssh_command_by_sudo_for_create(ssh,"chmod 777 #{args.path}/#{args.site_name} -R")
|
||||||
|
@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
|
|
@ -4,7 +4,6 @@ namespace :create_site do
|
||||||
desc "Create Site Script"
|
desc "Create Site Script"
|
||||||
task :create_site,[:git_template_url,:git_extension_url,:git_url,:ip,:user,:password,:site_name,:domain_name,:port,:db_name,:path,:site_construct_id] => :environment do |task,args|
|
task :create_site,[:git_template_url,:git_extension_url,:git_url,:ip,:user,:password,:site_name,:domain_name,:port,:db_name,:path,:site_construct_id] => :environment do |task,args|
|
||||||
@password = args.password
|
@password = args.password
|
||||||
puts args
|
|
||||||
if args.site_construct_id.blank?
|
if args.site_construct_id.blank?
|
||||||
@site_construct = SiteConstruct.new
|
@site_construct = SiteConstruct.new
|
||||||
@site_construct.server_type = (SiteServer.where(:ip=>args.ip).first.server_name rescue args.ip)
|
@site_construct.server_type = (SiteServer.where(:ip=>args.ip).first.server_name rescue args.ip)
|
||||||
|
@ -56,11 +55,7 @@ namespace :create_site do
|
||||||
update_infos("restarting nginx")
|
update_infos("restarting nginx")
|
||||||
exec_ssh_command_by_sudo_for_create(ssh,"service nginx restart")
|
exec_ssh_command_by_sudo_for_create(ssh,"service nginx restart")
|
||||||
update_infos("finish restarting nginx")
|
update_infos("finish restarting nginx")
|
||||||
dir = Pathname.new(args.path)
|
exec_ssh_command_by_sudo_for_create(ssh,"mkdir -p #{args.path}")
|
||||||
while dir.to_s != '/' do
|
|
||||||
exec_ssh_command_by_sudo_for_create(ssh,"mkdir #{dir}")
|
|
||||||
dir = dir.dirname
|
|
||||||
end
|
|
||||||
update_infos("cloning orbit4-5 from #{args.git_url} to #{args.path}/#{args.site_name}")
|
update_infos("cloning orbit4-5 from #{args.git_url} to #{args.path}/#{args.site_name}")
|
||||||
exec_ssh_command_by_sudo_for_create(ssh,"git clone #{args.git_url} #{args.path}/#{args.site_name}")
|
exec_ssh_command_by_sudo_for_create(ssh,"git clone #{args.git_url} #{args.path}/#{args.site_name}")
|
||||||
exec_ssh_command_by_sudo_for_create(ssh,"bash -l -c 'cd #{args.path}/#{args.site_name} && git submodule add #{args.git_template_url} app/templates/default-theme'")
|
exec_ssh_command_by_sudo_for_create(ssh,"bash -l -c 'cd #{args.path}/#{args.site_name} && git submodule add #{args.git_template_url} app/templates/default-theme'")
|
||||||
|
|
Loading…
Reference in New Issue