Commit 85b736c87855217fc9d6d133f17d8d35184301fa

Authored by Antonio Terceiro
2 parents ae97efa0 935a6418

Merge branch 'backup-restore' into 'master'

backup/restore rake tasks

see commit message

See merge request !469
Showing 1 changed file with 105 additions and 6 deletions   Show diff stats
lib/tasks/backup.rake
1   -desc "Creates a backup of the user files stored in public/"
2   -task :backup do
3   - dirs = Dir.glob('public/images/[0-9][0-9][0-9][0-9]') + ['public/articles', 'public/thumbnails', 'public/user_themes'].select { |d| File.exists?(d) }
4   - tarball = 'backups/files-' + Time.now.strftime('%Y-%m-%d-%R') + '.tar'
  1 +task :load_backup_config do
  2 + $config = YAML.load_file('config/database.yml')
  3 +end
  4 +
  5 +task :check_backup_support => :load_backup_config do
  6 + if $config['production']['adapter'] != 'postgresql'
  7 + fail("Only PostgreSQL is supported for backups at the moment")
  8 + end
  9 +end
  10 +
  11 +backup_dirs = [
  12 + 'public/image_uploads',
  13 + 'public/articles',
  14 + 'public/thumbnails',
  15 + 'public/user_themes',
  16 +]
  17 +
  18 +desc "Creates a backup of the database and uploaded files"
  19 +task :backup => :check_backup_support do
  20 + dirs = backup_dirs.select { |d| File.exists?(d) }
  21 +
  22 + backup_name = Time.now.strftime('%Y-%m-%d-%R')
  23 + backup_file = File.join('tmp/backup', backup_name) + '.tar.gz'
  24 + mkdir_p 'tmp/backup'
  25 + dump = File.join('tmp/backup', backup_name) + '.sql'
  26 +
  27 + database = $config['production']['database']
  28 + sh "pg_dump #{database} > #{dump}"
  29 +
  30 + sh 'tar', 'caf', backup_file, dump, *dirs
  31 + rm_f dump
  32 +
  33 + puts "****************************************************"
  34 + puts "Backup in #{backup_file} !"
  35 + puts
  36 + puts "To restore, use:"
  37 + puts "$ rake restore BACKUP=#{backup_file}"
  38 + puts "****************************************************"
  39 +end
  40 +
  41 +def invalid_backup!(message, items=[])
  42 + puts "E: #{message}"
  43 + items.each do |i|
  44 + puts "E: - #{i}"
  45 + end
  46 + puts "E: Is this a backup archive created by Noosfero with \`rake backup\`?"
  47 + exit 1
  48 +end
  49 +
  50 +desc "Restores a backup created previousy with \`rake backup\`"
  51 +task :restore => :check_backup_support do
  52 + backup = ENV["BACKUP"]
  53 + unless backup
  54 + puts "usage: rake restore BACKUP=/path/to/backup"
  55 + exit 1
  56 + end
  57 +
  58 + files = `tar taf #{backup}`.split
  59 +
  60 + # validate files in the backup
  61 + invalid_files = []
  62 + files.each do |f|
  63 + if f !~ /tmp\/backup\// && (backup_dirs.none? { |d| f =~ /^#{d}\// })
  64 + invalid_files << f
  65 + end
  66 + end
  67 + if invalid_files.size > 0
  68 + invalid_backup!("Invalid files found in the backup archive", invalid_files)
  69 + end
  70 +
  71 + # find database dump in the archive
  72 + dumps = files.select do |f|
  73 + File.dirname(f) == 'tmp/backup' && f =~ /\.sql$/
  74 + end
  75 + if dumps.size == 0
  76 + invalid_backup!("Could not find a database dump in the archive.")
  77 + elsif dumps.size > 1
  78 + invalid_backup!("Multiple database dumps found in the archive:", dumps)
  79 + end
  80 + dump = dumps.first
  81 +
  82 + database = $config['production']['database']
  83 + username = $config['production']['username']
  84 +
  85 + puts "WARNING: backups should be restored to an empty database, otherwise"
  86 + puts "data from the backup may not be loaded properly."
  87 + puts
  88 + puts 'You can remove the existing database and create a new one with:'
  89 + puts
  90 + puts "$ sudo -u postgres dropdb #{database}"
  91 + puts "$ sudo -u postgres createdb #{database} --owner #{username}"
  92 + puts
  93 + print "Are you sure you want to continue (y/N)? "
  94 + response = $stdin.gets.strip
  95 + unless ['y', 'yes'].include?(response.downcase)
  96 + puts "*** ABORTED."
  97 + exit 1
  98 + end
  99 +
  100 + sh 'tar', 'xaf', backup
  101 + sh "rails dbconsole production < #{dump}"
  102 + rm_f dump
5 103  
6   - mkdir_p(File.dirname(tarball))
7   - sh('tar', 'cf', tarball, *dirs)
  104 + puts "****************************************************"
  105 + puts "Backup restored!"
  106 + puts "****************************************************"
8 107 end
... ...