#!/usr/bin/rake =begin Subversion Backup Tool Copyright 2006 by Simon Strandgaard =end $settings = { 'backup_tmpdir' => 'hotcopy', 'backup_zipdir' => 'resdir', 'backup_repository_path' => 'repo', 'backup_zipprefix' => 'myproject_', 'ftp_server' => 'ftp.example.com', 'ftp_user' => 'example.com', 'ftp_password' => 'secretpassword', 'smtp_server' => 'mail.example.com', 'mail_prefix' => '[backup]', 'mail_from' => 'server@example.com', 'mail_to' => ['user1@example.com', 'user2@example.com'] } task :default => :upload BEGIN { ts = Time.now $time_begin = ts msg = "BEGIN: #{ts}. PID=#{$$}." $stdout.puts "[STDOUT] " + msg $stderr.puts "[STDERR] " + msg } END { ts = Time.now diff = ts - $time_begin msg = "END: #{ts}, total #{diff} seconds." $stdout.puts "[STDOUT] " + msg $stderr.puts "[STDERR] " + msg } TMP_DIR = $settings['backup_tmpdir'] ZIP_DIR = $settings['backup_zipdir'] ZIP_PREFIX = $settings['backup_zipprefix'] REPO_PATH = $settings['backup_repository_path'] FTP_SERVER = $settings['ftp_server'] FTP_USER = $settings['ftp_user'] FTP_PASS = $settings['ftp_password'] MAIL_PREFIX = $settings['mail_prefix'] SMTP_SERVER = $settings['smtp_server'] MAIL_FROM = $settings['mail_from'] MAIL_TO = $settings['mail_to'] require 'fileutils' require 'net/ftp' require 'net/smtp' ########################################################################## desc 'print info about this system' task :info do puts "\nRUBY-VERSION:\n#{RUBY_VERSION}\n" puts "\nRAKE-VERSION:" system('rake --version') puts "\nSYSTEM-NAME:" system('uname', '-a') puts "\nSYSTEM-UPTIME:" system('uptime') puts "\nLAST-LOGINS:" system('last | head -n 20') puts "\nSHELL-ENVIRONMENT:" system('env') puts "\nRAKE-SETTINGS:" ary = $settings.map do |k,v| "#{k}=#{v.inspect}" end puts ary.sort.join("\n") puts "\n\n\n" end ########################################################################## ## create a hotcopy ## ########################################################################## file TMP_DIR => REPO_PATH do sh "svnadmin hotcopy #{REPO_PATH} #{TMP_DIR}" end ########################################################################## ## compress a repository ## ########################################################################## def tmpdir_revision revstr = `svnlook youngest #{TMP_DIR}` revstr.match(/\d+/).to_s end def tmpdir_size s = `du -c -h #{TMP_DIR} | tail -n 1` ary = s.scan(/(\d\S{1,10}?)\s+(total)/i) (ary.size > 0) ? ary[0][0] : 'UNKNOWN' end file ZIP_DIR => TMP_DIR do revstr = tmpdir_revision date = Time.now.strftime('%Y%m%d') zipfile = "#{ZIP_PREFIX}#{date}_rev#{revstr}.tgz" zippath = File.join(ZIP_DIR, zipfile) size1 = tmpdir_size FileUtils.mkdir ZIP_DIR sh "tar czf #{zippath} #{TMP_DIR}" size2 = File.stat(zippath).size a = "#{TMP_DIR.inspect} (#{size1} bytes)" b = "#{zippath.inspect} (#{size2} bytes)" puts "compressed #{a} -> #{b}" end ########################################################################## task :upload => ZIP_DIR do Dir.chdir ZIP_DIR do files = Dir.glob '*' puts "files to upload:" p files h = Net::FTP.new FTP_SERVER h.login FTP_USER, FTP_PASS h.chdir 'backup' files.each do |file| h.putbinaryfile file h.sendcmd "chmod 750 #{file}" end puts "\nfiles uploaded:" puts h.list h.close `touch OK` end puts "Upload OK" end ########################################################################## desc 'send mail to admins' task :notify do date = Time.now.strftime('%a, %d %b %y %H:%M:%S +0100') subject = "#{MAIL_PREFIX} NOZIP, ERROR!" body = IO.read('lerr') body += "\n\n\n-------\n\n\n" body += IO.read('lout') if File.exists?(ZIP_DIR) Dir.chdir(ZIP_DIR) do status = File.exists?('OK') ? 'OK' : 'ERROR!' files = Dir.glob('*').reject{|i| i == 'OK' } str = files.join(', ') subject = "#{MAIL_PREFIX} #{str}, #{status}" end end puts "sending mail notification" MAIL_TO.each do |to| body = <true} FileUtils.rm_r ZIP_DIR, {:force=>true} end