Module: Mccloud::Provider::Core::VmCommand
- Included in:
- Vm
- Defined in:
- lib/mccloud/provider/core/vm/ssh.rb,
lib/mccloud/provider/core/vm/rsync.rb,
lib/mccloud/provider/core/vm/ssh_forward.rb,
lib/mccloud/provider/core/vm/ssh_bootstrap.rb
Instance Method Summary collapse
-
#adjust_rsync_path(path) ⇒ Object
cygwin rsync path must be adjusted to work.
- #bg_exec(ssh_command, options) ⇒ Object
- #execute(command = nil, options = {}) ⇒ Object
- #fg_exec(ssh_command, options) ⇒ Object
-
#rsync(src, dest = "tmp", options = {}) ⇒ Object
blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/185404 This should work on windows too now This will result in a ShellResult structure with stdout, stderr and status.
- #rsync_permissions ⇒ Object
- #share ⇒ Object
- #share_file(name, dest, src, options = {}) ⇒ Object
- #share_folder(name, dest, src, options = {}) ⇒ Object
- #share_sync(src, dest, options = {}) ⇒ Object
- #ssh(command = nil, options = {}) ⇒ Object
- #ssh_bootstrap(command, bootstrap_options = {}) ⇒ Object
- #ssh_commandline_options(options) ⇒ Object
- #ssh_forward(options = nil) ⇒ Object
- #ssh_tunnel_start(forwardings) ⇒ Object
- #ssh_tunnel_stop ⇒ Object
- #sudo(command = nil, options = {}) ⇒ Object
- #sudo_string(command = nil, options = {}) ⇒ Object
- #windows_client? ⇒ Boolean
Instance Method Details
#adjust_rsync_path(path) ⇒ Object
cygwin rsync path must be adjusted to work
38 39 40 41 |
# File 'lib/mccloud/provider/core/vm/rsync.rb', line 38 def adjust_rsync_path(path) return path unless windows_client? path.gsub(/^(\w):/) { "/cygdrive/#{$1}" } end |
#bg_exec(ssh_command, options) ⇒ Object
75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 |
# File 'lib/mccloud/provider/core/vm/ssh.rb', line 75 def bg_exec(ssh_command,) result=ShellResult.new("","",-1) IO.popen("#{ssh_command}") { |p| p.each_line{ |l| result.stdout+=l print l unless [:mute] } result.status=Process.waitpid2(p.pid)[1].exitstatus if result.status!=0 raise ::Mccloud::Error, "Exit status was not 0 but #{result.status}" unless [:mute] end } return result end |
#execute(command = nil, options = {}) ⇒ Object
57 58 59 |
# File 'lib/mccloud/provider/core/vm/ssh.rb', line 57 def execute(command=nil,={}) ssh(command,) end |
#fg_exec(ssh_command, options) ⇒ Object
61 62 63 64 65 66 67 68 69 70 71 72 73 |
# File 'lib/mccloud/provider/core/vm/ssh.rb', line 61 def fg_exec(ssh_command,) # Some hackery going on here. On Mac OS X Leopard (10.5), exec fails # (GH-51). As a workaround, we fork and wait. On all other platforms, # we simply exec. pid = nil pid = fork if Mccloud::Util::Platform.leopard? || Mccloud::Util::Platform.tiger? env.logger.info "Executing internal ssh command" # Add terminal env.logger.info ssh_command+" -t" Kernel.exec ssh_command if pid.nil? Process.wait(pid) if pid end |
#rsync(src, dest = "tmp", options = {}) ⇒ Object
blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/185404 This should work on windows too now This will result in a ShellResult structure with stdout, stderr and status
51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 |
# File 'lib/mccloud/provider/core/vm/rsync.rb', line 51 def rsync(src,dest="tmp", = {}) unless !File.exists?(src) env.ui.info "[#{@name}] - rsyncing #{src}" mute="-v" mute="-q -t" if [:mute] if Pathname.new(dest).absolute? dest_path = dest else dest_path = File.join(File::Separator,dest) end if dest_path == File::Separator puts "no way we gonna rsync --delete the root filesystem" exit -1 end command="rsync #{} --exclude '.DS_Store' --exclude '.hg' --exclude '.git' #{mute} --delete-excluded --delete -az -e 'ssh #{()}' '#{adjust_rsync_path(src)}' '#{@user}@#{self.ip_address}:#{dest_path}'" else env.ui.info "[#{@name}] - rsync error: #{src} does no exist" exit end result=ShellResult.new("","",-1) env.logger.info "#{command}" unless [:mute] IO.popen("#{command}") { |p| p.each_line{ |l| result.stdout+=l print l unless [:mute] } result.status=Process.waitpid2(p.pid)[1].exitstatus if result.status!=0 env.ui.info "Exit status was not 0 but #{result.status}" unless [:mute] end } return result end |
#rsync_permissions ⇒ Object
44 45 46 |
# File 'lib/mccloud/provider/core/vm/rsync.rb', line 44 def '--chmod=ugo=rwX' if windows_client? end |
#share ⇒ Object
15 16 17 18 19 20 21 22 23 24 25 26 |
# File 'lib/mccloud/provider/core/vm/rsync.rb', line 15 def share @shared_folders.each do |folder| self.execute("test -d '#{folder[:dest]}' || mkdir -p '#{folder[:dest]}' ") clean_src_path=File.join(Pathname.new(folder[:src])..cleanpath.to_s,'/') rsync(clean_src_path,folder[:dest],folder[:options]) end @shared_files.each do |file| self.execute("test -d '#{File.dirname(file[:dest])}' || mkdir -p '#{File.dirname(file[:dest])}' ") clean_src_path=Pathname.new(file[:src])..cleanpath.to_s rsync(clean_src_path,file[:dest],file[:options]) end end |
#share_file(name, dest, src, options = {}) ⇒ Object
10 11 12 13 |
# File 'lib/mccloud/provider/core/vm/rsync.rb', line 10 def share_file(name , dest,src,={}) ={:mute => false}.merge() @shared_files << { :name => name, :dest => dest, :src => src, :options => } end |
#share_folder(name, dest, src, options = {}) ⇒ Object
5 6 7 8 |
# File 'lib/mccloud/provider/core/vm/rsync.rb', line 5 def share_folder(name , dest,src,={}) ={:mute => false}.merge() @shared_folders << { :name => name, :dest => dest, :src => src, :options => } end |
#share_sync(src, dest, options = {}) ⇒ Object
28 29 30 31 |
# File 'lib/mccloud/provider/core/vm/rsync.rb', line 28 def share_sync(src, dest, = {}) clean_src_path=File.join(Pathname.new(src).cleanpath.to_s,'/') rsync(clean_src_path,dest,) end |
#ssh(command = nil, options = {}) ⇒ Object
91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 |
# File 'lib/mccloud/provider/core/vm/ssh.rb', line 91 def ssh(command=nil,={}) # Command line options extended_command="#{command}" unless .nil? extended_command="screen -R \\\"#{command}\\\"" unless [:screen].nil? end host_ip=self.ip_address unless host_ip.nil? || host_ip=="" ssh_command="ssh #{()} #{host_ip} \"#{extended_command}\"" unless .nil? || [:mute] env.ui.info "[#{@name}] - ssh -p #{@port} #{@user}@#{host_ip} \"#{command}\"" end if command.nil? || command=="" fg_exec(ssh_command,) else unless [:password] bg_exec(ssh_command,) else env.ui.info "[#{@name}] - attempting password login" real_user = @user real_user = [:user] if [:user] if [:user] Net::SSH.start(host_ip, real_user, :password => [:password] ) do |ssh2| result = ssh2.exec!(command) puts result end else end end end else env.ui.error "Can't ssh into '#{@name} as we couldn't figure out it's ip-address" end end |
#ssh_bootstrap(command, bootstrap_options = {}) ⇒ Object
9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 |
# File 'lib/mccloud/provider/core/vm/ssh_bootstrap.rb', line 9 def ssh_bootstrap(command,= {}) begin = Hash.new [:port] = @port unless @bootstrap_user.nil? [:user] = @bootstrap_user end unless @bootstrap_password.nil? [:password] = @bootstrap_password end if self.running? scriptname=command.nil? ? @bootstrap : command unless scriptname.nil? env.logger.info "[#{@name}] - Using #{scriptname} as bootstrap script" full_scriptname=Pathname.new(scriptname).(env.root_path).to_s env.logger.info "[#{@name}] - Full #{full_scriptname} " env.ui.info "[#{@name}] - Uploading bootstrap code to machine #{@name}" unless !File.exists?(full_scriptname) begin self.transfer(full_scriptname,"/tmp/bootstrap.sh",) rescue Net::SSH::AuthenticationFailed raise ::Mccloud::Error, "[#{@name}] - Authentication problem \n" rescue Exception => ex raise ::Mccloud::Error, "[#{@name}] - Error uploading file #{full_scriptname} #{ex.inspect}\n" end env.ui.info "[#{@name}] - Enabling the bootstrap code to run" result=self.execute("chmod +x /tmp/bootstrap.sh && #{self.sudo_string("/tmp/bootstrap.sh",)}",) else raise ::Mccloud::Error, "[#{@name}] - Error: bootstrap file #{scriptname} does not exist" end else env.ui.warn "[#{@name}] - You didn't specify a bootstrap, hope you know what you're doing." end else env.ui.warn "[#{@name}] - Server is not running, so bootstrapping will do no good" end rescue ::Net::SSH::AuthenticationFailed => ex raise ::Mccloud::Error, "[#{@name}] - Authentication failure #{ex.to_s}" end end |
#ssh_commandline_options(options) ⇒ Object
8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
# File 'lib/mccloud/provider/core/vm/ssh.rb', line 8 def () = [ "-q", #Suppress warning messages # "-T", #Pseudo-terminal will not be allocated because stdin is not a terminal. "-t", "-p #{@port}", "-o UserKnownHostsFile=/dev/null", "-o StrictHostKeyChecking=no", #"-o IdentitiesOnly=yes", "-o VerifyHostKeyDNS=no", "-o ControlMaster=auto", "-o \"ControlPath=~/.ssh/master-%r@%h:%p\"" ] unless @private_key_path.nil? << "-i #{@private_key_path}" end if @agent_forwarding << "-A" end ="#{.join(" ")} ".strip unless [:user] user_option=@user.nil? ? "" : "-l #{@user}" else user_option=@user.nil? ? "" : "-l #{[:user]}" end return "#{} #{user_option}" end |
#ssh_forward(options = nil) ⇒ Object
7 8 9 |
# File 'lib/mccloud/provider/core/vm/ssh_forward.rb', line 7 def ssh_forward(=nil) return ssh_tunnel_start(@forwardings) end |
#ssh_tunnel_start(forwardings) ⇒ Object
11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
# File 'lib/mccloud/provider/core/vm/ssh_forward.rb', line 11 def ssh_tunnel_start(forwardings) unless forwardings.empty? @forward_threads<< Thread.new(self) { |vm| env=vm.env begin ={ :paranoid => false, :keys_only => true} [:keys]= [ vm.private_key_path ] unless vm.private_key_path.nil? Net::SSH.start(vm.ip_address, vm.user, ) do |ssh_session| vm.forwardings.each do |f| begin env.ui.info "Forwarding remote port #{f.remote} on #{vm.ip_address} from #{@name} to localhost port #{f.local}" ssh_session.forward.local(f.local.to_i, "127.0.0.1",f.remote.to_i) #ssh_session.forward.local(f.local.to_i, vm.ip_address,f.remote.to_i) rescue Errno::EACCES env.ui.error "Error - Access denied to forward remote port #{f.remote} from #{@name} to localhost port #{f.local}" end end ssh_session.loop {true} end rescue IOError env.ui.error "IOError - maybe there is no listener on the port (yet?)" end } end return @forward_threads end |
#ssh_tunnel_stop ⇒ Object
38 39 40 41 42 |
# File 'lib/mccloud/provider/core/vm/ssh_forward.rb', line 38 def ssh_tunnel_stop @forward_threads.each do |thread| Thread.kill(thread) end end |
#sudo(command = nil, options = {}) ⇒ Object
40 41 42 43 |
# File 'lib/mccloud/provider/core/vm/ssh.rb', line 40 def sudo(command=nil,={}) self.execute("#{sudo_string(command,)}",) end |
#sudo_string(command = nil, options = {}) ⇒ Object
45 46 47 48 49 50 51 52 53 54 55 |
# File 'lib/mccloud/provider/core/vm/ssh.rb', line 45 def sudo_string(command=nil,={}) prefix="sudo -E " # Check if we override the user in the options unless [:user] prefix="" if self.user == "root" else prefix="" if [:user] == "root" end return "#{prefix}#{command}" end |