Commit 85b736c87855217fc9d6d133f17d8d35184301fa
Exists in
master
and in
29 other branches
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 | ... | ... |