// capistrano deployment strategy used when you have sftp access only (no ssh access)
require 'capistrano/recipes/deploy/strategy/base'
require 'fileutils'
require 'tempfile'
require 'net/ssh'
require 'net/sftp'
require 'find'
module Capistrano
module Deploy
module Strategy
class SftpCopy < Base
def deploy!
logger.debug "getting (via #{copy_strategy}) revision #{revision} to #{destination}"
system(command)
File.open(File.join(destination, "REVISION"), "w") { |f| f.puts(revision) }
logger.debug "Connecting to sftp user = #{configuration[:user]}"
Net::SSH.start(configuration[:host], configuration[:user], configuration[:password]) do |ssh|
ssh.sftp.connect do |sftp|
logger.debug "Creating directory: #{remote_dir}"
sftp.mkdir remote_dir, :permissions => 0755
logger.debug "Uploading files from #{destination} to #{remote_dir}"
logger.debug "Why don't you grab a cup of coffee while you wait, i might be busy for some time...\nJust sit back and enjoy the show..."
Find.find(destination) do |file|
if File.stat(file).directory?
remote_directory = remote_dir + file.sub(destination, '')
begin
sftp.stat(remote_directory)
rescue Net::SFTP::Operations::StatusException => e
raise "BOEM" unless e.code == 2
sftp.mkdir(remote_directory, :permissions => 0755)
end
else
remote_file = remote_dir + file.sub(destination, '')
sftp.put_file file, remote_file
sftp.setstat(remote_file, :permissions => 0644)
end
end
logger.debug "RENAMING DIRECTORIES"
sftp.rename "#{configuration[:copy_remote_dir]}/current", "#{configuration[:copy_remote_dir]}/#{(Time.now - 1.hour).utc.strftime("%Y%m%d%H%M%S")}"
sftp.rename "#{remote_dir}", "#{configuration[:copy_remote_dir]}/current"
end
end
ensure
logger.debug "Remove local export"
FileUtils.rm_rf destination rescue nil
end
def check!
super.check do |d|
end
end
private
def destination
@destination ||= File.join(tmpdir, File.basename(configuration[:release_path]))
end
def copy_strategy
@copy_strategy ||= configuration.fetch(:copy_strategy, :checkout)
end
def command
@command ||= case copy_strategy
when :checkout
source.checkout(revision, destination)
when :export
source.export(revision, destination)
end
end
def filename
@filename ||= File.join(tmpdir, "#{File.basename(destination)}.#{compression_extension}")
end
def tmpdir
@tmpdir ||= configuration[:copy_dir] || Dir.tmpdir
end
def remote_dir
@remote_dir ||= "#{configuration[:copy_remote_dir]}/#{File.basename(configuration[:release_path])}" || "/tmp"
end
end
end
end
end