backup 2.3.1 → 2.3.2.pre
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/CHANGELOG +16 -1
- data/README.textile +42 -177
- data/bin/backup +14 -17
- data/generators/backup/templates/config/backup.rb +26 -6
- data/generators/backup/templates/migrations/create_backup_tables.rb +3 -2
- data/generators/backup/templates/tasks/backup.rake +14 -17
- data/generators/backup_update/backup_update_generator.rb +50 -0
- data/generators/backup_update/templates/migrations/update_backup_tables.rb +27 -0
- data/lib/backup.rb +31 -30
- data/lib/backup/adapters/archive.rb +19 -54
- data/lib/backup/adapters/base.rb +55 -35
- data/lib/backup/adapters/custom.rb +15 -53
- data/lib/backup/adapters/mysql.rb +24 -55
- data/lib/backup/adapters/postgresql.rb +19 -54
- data/lib/backup/adapters/sqlite.rb +25 -0
- data/lib/backup/command_helper.rb +11 -0
- data/lib/backup/configuration/adapter.rb +4 -11
- data/lib/backup/configuration/adapter_options.rb +3 -14
- data/lib/backup/configuration/attributes.rb +19 -0
- data/lib/backup/configuration/base.rb +26 -9
- data/lib/backup/configuration/mail.rb +3 -9
- data/lib/backup/configuration/smtp.rb +3 -14
- data/lib/backup/configuration/storage.rb +3 -12
- data/lib/backup/connection/s3.rb +3 -1
- data/lib/backup/environment/unix.rb +4 -4
- data/lib/backup/mail/base.rb +8 -2
- data/lib/backup/mail/mail.txt +3 -3
- data/lib/backup/record/base.rb +65 -0
- data/lib/backup/record/ftp.rb +10 -69
- data/lib/backup/record/local.rb +26 -0
- data/lib/backup/record/s3.rb +9 -63
- data/lib/backup/record/scp.rb +9 -64
- data/lib/backup/record/sftp.rb +10 -68
- data/lib/backup/storage/ftp.rb +3 -1
- data/lib/backup/storage/local.rb +24 -0
- data/lib/backup/storage/s3.rb +3 -1
- data/lib/backup/storage/scp.rb +3 -1
- data/lib/backup/storage/sftp.rb +3 -1
- data/setup/backup.rb +27 -6
- data/setup/backup.sqlite3 +0 -0
- metadata +130 -60
- data/.document +0 -5
- data/.gitignore +0 -5
- data/Rakefile +0 -70
- data/backup.gemspec +0 -111
@@ -2,78 +2,40 @@ module Backup
|
|
2
2
|
module Adapters
|
3
3
|
class Custom < Backup::Adapters::Base
|
4
4
|
|
5
|
-
attr_accessor :
|
5
|
+
attr_accessor :commands
|
6
6
|
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
#
|
12
|
-
# First it will execute any given commands
|
13
|
-
# Then it will archive and compress every folder/file
|
14
|
-
# Then it will optionally encrypt the backed up file
|
15
|
-
# Then it will store it to the specified storage location
|
16
|
-
# Then it will record the data to the database
|
17
|
-
# Once this is all done, all the temporary files will be removed
|
18
|
-
#
|
19
|
-
# Wrapped inside of begin/ensure/end block to ensure the deletion of any files in the tmp directory
|
20
|
-
def initialize(trigger, procedure)
|
21
|
-
super
|
22
|
-
load_settings
|
23
|
-
|
24
|
-
begin
|
7
|
+
private
|
8
|
+
|
9
|
+
# Execute any given commands, then archive and compress every folder/file
|
10
|
+
def perform
|
25
11
|
execute_commands
|
26
12
|
targz
|
27
|
-
encrypt
|
28
|
-
store
|
29
|
-
record
|
30
|
-
notify
|
31
|
-
ensure
|
32
|
-
remove_tmp_files
|
33
13
|
end
|
34
|
-
end
|
35
|
-
|
36
|
-
private
|
37
14
|
|
38
15
|
# Executes the commands
|
39
16
|
def execute_commands
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
end
|
45
|
-
elsif commands.is_a?(String)
|
46
|
-
puts system_messages[:commands]
|
47
|
-
%x{ #{commands.gsub(':tmp_path', tmp_path)} }
|
17
|
+
return unless commands
|
18
|
+
log system_messages[:commands]
|
19
|
+
[*commands].each do |command|
|
20
|
+
run "#{command.gsub(':tmp_path', tmp_path)}"
|
48
21
|
end
|
49
22
|
end
|
50
23
|
|
51
24
|
# Archives and Compresses
|
52
25
|
def targz
|
53
|
-
|
54
|
-
|
26
|
+
log system_messages[:archiving]; log system_messages[:compressing]
|
27
|
+
run "tar -czf #{File.join(tmp_path, compressed_file)} #{File.join(tmp_path, '*')}"
|
55
28
|
end
|
56
29
|
|
57
|
-
|
58
|
-
|
59
|
-
if encrypt_with_password.is_a?(String)
|
60
|
-
puts system_messages[:encrypting]
|
61
|
-
%x{ openssl enc -des-cbc -in #{File.join(tmp_path, compressed_file)} -out #{File.join(tmp_path, encrypted_file)} -k #{encrypt_with_password} }
|
62
|
-
self.final_file = encrypted_file
|
63
|
-
end
|
30
|
+
def performed_file_extension
|
31
|
+
".tar"
|
64
32
|
end
|
65
|
-
|
33
|
+
|
66
34
|
# Loads the initial settings
|
67
35
|
def load_settings
|
68
|
-
self.trigger = procedure.trigger
|
69
36
|
self.commands = procedure.get_adapter_configuration.attributes['commands']
|
70
|
-
|
71
|
-
self.archived_file = "#{timestamp}.#{trigger.gsub(' ', '-')}.tar"
|
72
|
-
self.compressed_file = "#{archived_file}.gz"
|
73
|
-
self.encrypted_file = "#{compressed_file}.enc"
|
74
|
-
self.final_file = compressed_file
|
75
37
|
end
|
76
38
|
|
77
39
|
end
|
78
40
|
end
|
79
|
-
end
|
41
|
+
end
|
@@ -2,68 +2,36 @@ module Backup
|
|
2
2
|
module Adapters
|
3
3
|
class MySQL < Backup::Adapters::Base
|
4
4
|
|
5
|
-
attr_accessor :
|
6
|
-
|
7
|
-
# Initializes the Backup Process
|
8
|
-
#
|
9
|
-
# This will first load in any prefixed settings from the Backup::Adapters::Base
|
10
|
-
# Then it will add it's own settings.
|
11
|
-
#
|
12
|
-
# First it will create a compressed MySQL dump
|
13
|
-
# Then it will optionally encrypt the backed up file
|
14
|
-
# Then it will store it to the specified storage location
|
15
|
-
# Then it will record the data to the database
|
16
|
-
# Once this is all done, all the temporary files will be removed
|
17
|
-
#
|
18
|
-
# Wrapped inside of begin/ensure/end block to ensure the deletion of any files in the tmp directory
|
19
|
-
def initialize(trigger, procedure)
|
20
|
-
super
|
21
|
-
load_settings
|
22
|
-
|
23
|
-
begin
|
24
|
-
mysqldump
|
25
|
-
encrypt
|
26
|
-
store
|
27
|
-
record
|
28
|
-
notify
|
29
|
-
ensure
|
30
|
-
remove_tmp_files
|
31
|
-
end
|
32
|
-
end
|
5
|
+
attr_accessor :user, :password, :database, :skip_tables, :host, :port, :socket, :additional_options, :tables
|
33
6
|
|
34
7
|
private
|
35
|
-
|
8
|
+
|
36
9
|
# Dumps and Compresses the MySQL file
|
10
|
+
def perform
|
11
|
+
log system_messages[:mysqldump]; log system_messages[:compressing]
|
12
|
+
run "#{mysqldump} -u #{user} --password='#{password}' #{options} #{additional_options} #{database} #{tables_to_include} #{tables_to_skip} | gzip -f --best > #{File.join(tmp_path, compressed_file)}"
|
13
|
+
end
|
14
|
+
|
37
15
|
def mysqldump
|
38
|
-
|
39
|
-
|
16
|
+
# try to determine the full path, and fall back to myqsldump if not found
|
17
|
+
cmd = `which mysqldump`.chomp
|
18
|
+
cmd = 'mysqldump' if cmd.empty?
|
19
|
+
cmd
|
40
20
|
end
|
41
21
|
|
42
|
-
|
43
|
-
|
44
|
-
if encrypt_with_password.is_a?(String)
|
45
|
-
puts system_messages[:encrypting]
|
46
|
-
%x{ openssl enc -des-cbc -in #{File.join(tmp_path, compressed_file)} -out #{File.join(tmp_path, encrypted_file)} -k #{encrypt_with_password} }
|
47
|
-
self.final_file = encrypted_file
|
48
|
-
end
|
22
|
+
def performed_file_extension
|
23
|
+
".sql"
|
49
24
|
end
|
50
|
-
|
25
|
+
|
51
26
|
# Loads the initial settings
|
52
27
|
def load_settings
|
53
|
-
|
54
|
-
|
55
|
-
%w(user password database skip_tables additional_options).each do |attribute|
|
28
|
+
%w(user password database tables skip_tables additional_options).each do |attribute|
|
56
29
|
send(:"#{attribute}=", procedure.get_adapter_configuration.attributes[attribute])
|
57
30
|
end
|
58
31
|
|
59
32
|
%w(host port socket).each do |attribute|
|
60
33
|
send(:"#{attribute}=", procedure.get_adapter_configuration.get_options.attributes[attribute])
|
61
34
|
end
|
62
|
-
|
63
|
-
self.dumped_file = "#{timestamp}.#{trigger.gsub(' ', '-')}.sql"
|
64
|
-
self.compressed_file = "#{dumped_file}.gz"
|
65
|
-
self.encrypted_file = "#{compressed_file}.enc"
|
66
|
-
self.final_file = compressed_file
|
67
35
|
end
|
68
36
|
|
69
37
|
# Returns a list of options in MySQL syntax
|
@@ -77,15 +45,16 @@ module Backup
|
|
77
45
|
|
78
46
|
# Returns a list of tables to skip in MySQL syntax
|
79
47
|
def tables_to_skip
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
48
|
+
return "" unless skip_tables
|
49
|
+
[*skip_tables].map {|table| " --ignore-table='#{database}.#{table}' "}
|
50
|
+
end
|
51
|
+
|
52
|
+
# Returns a list of tables to include in MySQL syntax
|
53
|
+
def tables_to_include
|
54
|
+
return "" unless tables
|
55
|
+
[*tables].join(" ")
|
87
56
|
end
|
88
57
|
|
89
58
|
end
|
90
59
|
end
|
91
|
-
end
|
60
|
+
end
|
@@ -2,56 +2,31 @@ module Backup
|
|
2
2
|
module Adapters
|
3
3
|
class PostgreSQL < Backup::Adapters::Base
|
4
4
|
|
5
|
-
attr_accessor :
|
6
|
-
|
7
|
-
# Initializes the Backup Process
|
8
|
-
#
|
9
|
-
# This will first load in any prefixed settings from the Backup::Adapters::Base
|
10
|
-
# Then it will add it's own settings.
|
11
|
-
#
|
12
|
-
# First it will create a compressed PostgreSQL dump
|
13
|
-
# Then it will optionally encrypt the backed up file
|
14
|
-
# Then it will store it to the specified storage location
|
15
|
-
# Then it will record the data to the database
|
16
|
-
# Once this is all done, all the temporary files will be removed
|
17
|
-
#
|
18
|
-
# Wrapped inside of begin/ensure/end block to ensure the deletion of any files in the tmp directory
|
19
|
-
def initialize(trigger, procedure)
|
20
|
-
super
|
21
|
-
load_settings
|
22
|
-
|
23
|
-
begin
|
24
|
-
pg_dump
|
25
|
-
encrypt
|
26
|
-
store
|
27
|
-
record
|
28
|
-
notify
|
29
|
-
ensure
|
30
|
-
remove_tmp_files
|
31
|
-
end
|
32
|
-
end
|
5
|
+
attr_accessor :user, :password, :database, :skip_tables, :host, :port, :socket, :additional_options
|
33
6
|
|
34
7
|
private
|
35
|
-
|
8
|
+
|
36
9
|
# Dumps and Compresses the PostgreSQL file
|
10
|
+
def perform
|
11
|
+
log system_messages[:pgdump]; log system_messages[:compressing]
|
12
|
+
ENV['PGPASSWORD'] = password
|
13
|
+
run "#{pg_dump} -U #{user} #{options} #{additional_options} #{tables_to_skip} #{database} | gzip -f --best > #{File.join(tmp_path, compressed_file)}"
|
14
|
+
ENV['PGPASSWORD'] = nil
|
15
|
+
end
|
16
|
+
|
37
17
|
def pg_dump
|
38
|
-
|
39
|
-
|
18
|
+
# try to determine the full path, and fall back to pg_dump if not found
|
19
|
+
cmd = `which pg_dump`.chomp
|
20
|
+
cmd = 'pg_dump' if cmd.empty?
|
21
|
+
cmd
|
40
22
|
end
|
41
23
|
|
42
|
-
|
43
|
-
|
44
|
-
if encrypt_with_password.is_a?(String)
|
45
|
-
puts system_messages[:encrypting]
|
46
|
-
%x{ openssl enc -des-cbc -in #{File.join(tmp_path, compressed_file)} -out #{File.join(tmp_path, encrypted_file)} -k #{encrypt_with_password} }
|
47
|
-
self.final_file = encrypted_file
|
48
|
-
end
|
24
|
+
def performed_file_extension
|
25
|
+
".sql"
|
49
26
|
end
|
50
|
-
|
27
|
+
|
51
28
|
# Loads the initial settings
|
52
29
|
def load_settings
|
53
|
-
self.trigger = procedure.trigger
|
54
|
-
|
55
30
|
%w(user password database skip_tables additional_options).each do |attribute|
|
56
31
|
send(:"#{attribute}=", procedure.get_adapter_configuration.attributes[attribute])
|
57
32
|
end
|
@@ -59,11 +34,6 @@ module Backup
|
|
59
34
|
%w(host port socket).each do |attribute|
|
60
35
|
send(:"#{attribute}=", procedure.get_adapter_configuration.get_options.attributes[attribute])
|
61
36
|
end
|
62
|
-
|
63
|
-
self.dumped_file = "#{timestamp}.#{trigger.gsub(' ', '-')}.sql"
|
64
|
-
self.compressed_file = "#{dumped_file}.gz"
|
65
|
-
self.encrypted_file = "#{compressed_file}.enc"
|
66
|
-
self.final_file = compressed_file
|
67
37
|
end
|
68
38
|
|
69
39
|
# Returns a list of options in PostgreSQL syntax
|
@@ -77,15 +47,10 @@ module Backup
|
|
77
47
|
|
78
48
|
# Returns a list of tables to skip in PostgreSQL syntax
|
79
49
|
def tables_to_skip
|
80
|
-
|
81
|
-
|
82
|
-
elsif skip_tables.is_a?(String)
|
83
|
-
" -T \"#{skip_tables}\" "
|
84
|
-
else
|
85
|
-
""
|
86
|
-
end
|
50
|
+
return "" unless skip_tables
|
51
|
+
[*skip_tables].map {|table| " -T \"#{table}\" "}
|
87
52
|
end
|
88
53
|
|
89
54
|
end
|
90
55
|
end
|
91
|
-
end
|
56
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module Backup
|
2
|
+
module Adapters
|
3
|
+
class SQLite < Base
|
4
|
+
|
5
|
+
attr_accessor :database
|
6
|
+
|
7
|
+
private
|
8
|
+
|
9
|
+
# Compress the sqlite file
|
10
|
+
def perform
|
11
|
+
log system_messages[:sqlite]
|
12
|
+
run "gzip -c --best #{database} > #{File.join(tmp_path, compressed_file)}"
|
13
|
+
end
|
14
|
+
|
15
|
+
def load_settings
|
16
|
+
self.database = procedure.get_adapter_configuration.attributes['database']
|
17
|
+
end
|
18
|
+
|
19
|
+
def performed_file_extension
|
20
|
+
""
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -1,18 +1,11 @@
|
|
1
1
|
module Backup
|
2
2
|
module Configuration
|
3
3
|
class Adapter
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
%w(files user password database skip_tables commands additional_options).each do |method|
|
8
|
-
define_method method do |value|
|
9
|
-
attributes[method] = value
|
10
|
-
end
|
11
|
-
end
|
4
|
+
extend Backup::Configuration::Attributes
|
5
|
+
generate_attributes %w(files exclude user password database tables skip_tables commands additional_options)
|
12
6
|
|
13
7
|
def initialize
|
14
|
-
@
|
15
|
-
@options = Backup::Configuration::AdapterOptions.new
|
8
|
+
@options = Backup::Configuration::AdapterOptions.new
|
16
9
|
end
|
17
10
|
|
18
11
|
def options(&block)
|
@@ -25,4 +18,4 @@ module Backup
|
|
25
18
|
|
26
19
|
end
|
27
20
|
end
|
28
|
-
end
|
21
|
+
end
|
@@ -1,19 +1,8 @@
|
|
1
1
|
module Backup
|
2
2
|
module Configuration
|
3
3
|
class AdapterOptions
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
%w(host port socket).each do |method|
|
8
|
-
define_method method do |value|
|
9
|
-
attributes[method] = value
|
10
|
-
end
|
11
|
-
end
|
12
|
-
|
13
|
-
def initialize
|
14
|
-
@attributes = {}
|
15
|
-
end
|
16
|
-
|
4
|
+
extend Backup::Configuration::Attributes
|
5
|
+
generate_attributes %w(host port socket)
|
17
6
|
end
|
18
7
|
end
|
19
|
-
end
|
8
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module Backup
|
2
|
+
module Configuration
|
3
|
+
module Attributes
|
4
|
+
|
5
|
+
def generate_attributes(*attrs)
|
6
|
+
define_method :attributes do
|
7
|
+
@attributes ||= {}
|
8
|
+
end
|
9
|
+
|
10
|
+
attrs.flatten.each do |att|
|
11
|
+
define_method att do |value|
|
12
|
+
self.attributes[att.to_s] = value
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
@@ -1,16 +1,12 @@
|
|
1
1
|
module Backup
|
2
2
|
module Configuration
|
3
3
|
class Base
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
attributes[method] = value
|
9
|
-
end
|
10
|
-
end
|
4
|
+
extend Backup::Configuration::Attributes
|
5
|
+
generate_attributes %w(encrypt_with_password keep_backups notify)
|
6
|
+
|
7
|
+
attr_accessor :trigger, :storage_name, :adapter_name
|
11
8
|
|
12
9
|
def initialize(trigger)
|
13
|
-
@attributes = {}
|
14
10
|
@trigger = trigger
|
15
11
|
@adapter_configuration = Backup::Configuration::Adapter.new
|
16
12
|
@storage_configuration = Backup::Configuration::Storage.new
|
@@ -25,6 +21,27 @@ module Backup
|
|
25
21
|
@storage_name = storage
|
26
22
|
@storage_configuration.instance_eval &block
|
27
23
|
end
|
24
|
+
|
25
|
+
# Initializes the storing process depending on the store settings
|
26
|
+
def initialize_storage(adapter)
|
27
|
+
case @storage_name.to_sym
|
28
|
+
when :s3 then Backup::Storage::S3.new(adapter)
|
29
|
+
when :scp then Backup::Storage::SCP.new(adapter)
|
30
|
+
when :ftp then Backup::Storage::FTP.new(adapter)
|
31
|
+
when :sftp then Backup::Storage::SFTP.new(adapter)
|
32
|
+
when :local then Backup::Storage::Local.new(adapter)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def initialize_record
|
37
|
+
case @storage_name.to_sym
|
38
|
+
when :s3 then Backup::Record::S3.new
|
39
|
+
when :scp then Backup::Record::SCP.new
|
40
|
+
when :ftp then Backup::Record::FTP.new
|
41
|
+
when :sftp then Backup::Record::SFTP.new
|
42
|
+
when :local then Backup::Record::Local.new
|
43
|
+
end
|
44
|
+
end
|
28
45
|
|
29
46
|
def get_adapter_configuration
|
30
47
|
@adapter_configuration
|
@@ -35,4 +52,4 @@ module Backup
|
|
35
52
|
end
|
36
53
|
end
|
37
54
|
end
|
38
|
-
end
|
55
|
+
end
|