Created
July 11, 2011 12:01
-
-
Save mmrwoods/1075722 to your computer and use it in GitHub Desktop.
Copy dumb-ass daily backups to remote servers using scp, genius!
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env ruby | |
# Dumb-ass Remote Copy - Copy dumb-ass daily backups to remote servers using scp, genius! | |
# | |
# Copies today's sub-directory of local source directory to remote destination directory. | |
# Uses only ssh and scp, but requires batch mode / authorized keys. | |
# Does not "sync" files, today's destination directory is trashed and everything is copied. | |
# Copies recursively, maintaining directory structure on remote host, but does so by creating | |
# directories as required and executing scp once for each file to copy - slow, but robust. | |
# Create a /etc/dumb_ass_remote_copy.yml config file to override default configuration options. | |
# Remote host name/address must be provided, as sole command line argument or in config file. | |
require 'yaml' | |
require 'fileutils' | |
require 'find' | |
require 'shellwords' | |
include Shellwords | |
config = File.exist?("/etc/dumb_ass_remote_copy.yml") ? YAML::load_file("/etc/dumb_ass_remote_copy.yml") : {} | |
source = config['source'] || "/var/local/backup/daily/" | |
destination = config['destination'] || "backup/remote/" + `hostname`.chomp | |
host = ARGV.size == 1 ? ARGV[0].split('@').last : config['host'] | |
port = config['port'] || "22" | |
user = ARGV.size == 1 ? ARGV[0].split('@').first : ( config['user'] || `whoami`.chomp ) | |
raise(ArgumentError, "No host provided") if host.nil? || host.strip == "" | |
ssh_cmd = "ssh #{user}@#{host} -p #{port} -o ConnectionAttempts=3 -o BatchMode=yes" | |
puts "Ensuring #{destination} directory exists on #{destination}..." | |
system("#{ssh_cmd} 'test -d #{destination} || mkdir -p #{destination}'") | |
today = Time.now.strftime('%A').downcase | |
source_with_day = File.join(source, today) | |
destination_with_day = File.join(destination, today) | |
puts "Deleting #{destination_with_day} if exists on #{host['name']}..." | |
system("#{ssh_cmd} 'test -d #{destination_with_day} && /bin/rm -rf #{destination_with_day}'") | |
puts "Copying #{source_with_day} to #{user}@#{host}:#{destination_with_day}..." | |
Find.find(source_with_day) do |local_path| | |
if File.directory?(local_path) | |
puts "\n#{File.basename(local_path)}:" unless File.basename(local_path) == today | |
remote_dir = File.join(destination_with_day, local_path.sub(source_with_day,'')) | |
system("#{ssh_cmd} 'mkdir -p #{remote_dir}'") | |
else | |
puts " -> #{File.basename(local_path)}" | |
remote_path = File.join(destination_with_day, local_path.sub(source_with_day,'')) | |
system("scp -q -P #{port} -o ConnectionAttempts=3 -o BatchMode=yes \"#{local_path}\" #{user}@#{host}:\"#{shellescape(remote_path)}\"") | |
end | |
end | |
puts "\nCleaning up permissions in destination directory..." | |
system("#{ssh_cmd} 'find #{destination_with_day} -type d -exec chmod 700 \\{} \\;'") | |
system("#{ssh_cmd} 'find #{destination_with_day} -type f -exec chmod 600 \\{} \\;'") |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment