backup-gundua 2.3.1.1

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.
Files changed (52) hide show
  1. data/.document +5 -0
  2. data/.gitignore +5 -0
  3. data/CHANGELOG +77 -0
  4. data/LICENSE +9 -0
  5. data/README.textile +175 -0
  6. data/Rakefile +69 -0
  7. data/VERSION +1 -0
  8. data/backup.gemspec +123 -0
  9. data/bin/backup +124 -0
  10. data/generators/backup/backup_generator.rb +72 -0
  11. data/generators/backup/templates/config/backup.rb +202 -0
  12. data/generators/backup/templates/migrations/create_backup_tables.rb +18 -0
  13. data/generators/backup/templates/tasks/backup.rake +71 -0
  14. data/generators/backup_update/backup_update_generator.rb +50 -0
  15. data/generators/backup_update/templates/migrations/update_backup_tables.rb +27 -0
  16. data/lib/backup/adapters/archive.rb +34 -0
  17. data/lib/backup/adapters/base.rb +113 -0
  18. data/lib/backup/adapters/custom.rb +41 -0
  19. data/lib/backup/adapters/mysql.rb +54 -0
  20. data/lib/backup/adapters/postgresql.rb +56 -0
  21. data/lib/backup/adapters/sqlite.rb +25 -0
  22. data/lib/backup/command_helper.rb +11 -0
  23. data/lib/backup/configuration/adapter.rb +21 -0
  24. data/lib/backup/configuration/adapter_options.rb +8 -0
  25. data/lib/backup/configuration/attributes.rb +19 -0
  26. data/lib/backup/configuration/base.rb +55 -0
  27. data/lib/backup/configuration/helpers.rb +24 -0
  28. data/lib/backup/configuration/mail.rb +20 -0
  29. data/lib/backup/configuration/smtp.rb +8 -0
  30. data/lib/backup/configuration/storage.rb +8 -0
  31. data/lib/backup/connection/s3.rb +85 -0
  32. data/lib/backup/environment/base.rb +12 -0
  33. data/lib/backup/environment/rails.rb +17 -0
  34. data/lib/backup/environment/unix.rb +94 -0
  35. data/lib/backup/mail/base.rb +93 -0
  36. data/lib/backup/mail/mail.txt +7 -0
  37. data/lib/backup/record/base.rb +65 -0
  38. data/lib/backup/record/ftp.rb +37 -0
  39. data/lib/backup/record/local.rb +26 -0
  40. data/lib/backup/record/s3.rb +24 -0
  41. data/lib/backup/record/scp.rb +31 -0
  42. data/lib/backup/record/sftp.rb +36 -0
  43. data/lib/backup/storage/ftp.rb +36 -0
  44. data/lib/backup/storage/local.rb +24 -0
  45. data/lib/backup/storage/s3.rb +14 -0
  46. data/lib/backup/storage/scp.rb +28 -0
  47. data/lib/backup/storage/sftp.rb +29 -0
  48. data/lib/backup.rb +118 -0
  49. data/setup/backup.rb +202 -0
  50. data/setup/backup.sqlite3 +0 -0
  51. data/spec/configuration/attributes_spec.rb +35 -0
  52. metadata +185 -0
@@ -0,0 +1,31 @@
1
+ module Backup
2
+ module Record
3
+ class SCP < Backup::Record::Base
4
+
5
+ attr_accessor :ip, :user, :password
6
+
7
+ def load_specific_settings(adapter)
8
+ %w(ip user password path).each do |method|
9
+ send(:"#{method}=", adapter.procedure.get_storage_configuration.attributes[method])
10
+ end
11
+ end
12
+
13
+ private
14
+
15
+ def self.destroy_backups(procedure, backups)
16
+ ip = procedure.get_storage_configuration.attributes['ip']
17
+ user = procedure.get_storage_configuration.attributes['user']
18
+ password = procedure.get_storage_configuration.attributes['password']
19
+
20
+ Net::SSH.start(ip, user, :password => password) do |ssh|
21
+ backups.each do |backup|
22
+ puts "\nDestroying backup \"#{backup.filename}\" from path \"#{backup.path}\"."
23
+ ssh.exec("rm #{File.join(backup.path, backup.filename)}")
24
+ backup.destroy
25
+ end
26
+ end
27
+ end
28
+
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,36 @@
1
+ module Backup
2
+ module Record
3
+ class SFTP < Backup::Record::Base
4
+
5
+ attr_accessor :ip, :user, :password
6
+
7
+ def load_specific_settings(adapter)
8
+ %w(ip user password path).each do |method|
9
+ send(:"#{method}=", adapter.procedure.get_storage_configuration.attributes[method])
10
+ end
11
+ end
12
+
13
+ private
14
+
15
+ def self.destroy_backups(procedure, backups)
16
+ ip = procedure.get_storage_configuration.attributes['ip']
17
+ user = procedure.get_storage_configuration.attributes['user']
18
+ password = procedure.get_storage_configuration.attributes['password']
19
+
20
+ Net::SFTP.start(ip, user, :password => password) do |sftp|
21
+ backups.each do |backup|
22
+ puts "\nDestroying backup \"#{backup.filename}\" from path \"#{backup.path}\"."
23
+ begin
24
+ sftp.remove!(File.join(backup.path, backup.filename))
25
+ backup.destroy
26
+ rescue
27
+ puts "Could not find backup #{backup.path}/#{backup.filename}.."
28
+ backup.destroy
29
+ end
30
+ end
31
+ end
32
+ end
33
+
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,36 @@
1
+ module Backup
2
+ module Storage
3
+ class FTP
4
+
5
+ attr_accessor :user, :password, :ip, :path, :tmp_path, :final_file
6
+
7
+ # Stores the backup file on the remote server using FTP
8
+ def initialize(adapter)
9
+ %w(ip user password path).each do |method|
10
+ send("#{method}=", adapter.procedure.get_storage_configuration.attributes[method])
11
+ end
12
+
13
+ final_file = adapter.final_file
14
+ tmp_path = adapter.tmp_path
15
+
16
+ Net::FTP.open(ip, user, password) do |ftp|
17
+ begin
18
+ ftp.chdir(path)
19
+ rescue
20
+ puts "Could not find or access \"#{path}\" on \"#{ip}\", please ensure this directory exists and is accessible by the user \"#{user}\"."
21
+ exit
22
+ end
23
+
24
+ begin
25
+ puts "Storing \"#{final_file}\" to path \"#{path}\" on remote server (#{ip})."
26
+ ftp.putbinaryfile(File.join(tmp_path, final_file).gsub('\ ', ' '), File.join(path, final_file))
27
+ rescue
28
+ puts "Could not save file to backup server. Is the \"#{path}\" directory writable?"
29
+ exit
30
+ end
31
+ end
32
+ end
33
+
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,24 @@
1
+ module Backup
2
+ module Storage
3
+ class Local
4
+
5
+ include Backup::CommandHelper
6
+
7
+ # Store on same machine, preferentially in a different hard drive or in
8
+ # a mounted network path (NFS, Samba, etc)
9
+ attr_accessor :path, :tmp_path, :final_file
10
+
11
+ # Stores the backup file on local machine
12
+ def initialize(adapter)
13
+ self.path = adapter.procedure.get_storage_configuration.attributes['path']
14
+ self.tmp_path = adapter.tmp_path
15
+ self.final_file = adapter.final_file
16
+
17
+ run "mkdir -p #{path}"
18
+ run "cp #{File.join(tmp_path, final_file).gsub('\ ', ' ')} #{File.join(path, final_file)}"
19
+ end
20
+
21
+ end
22
+ end
23
+ end
24
+
@@ -0,0 +1,14 @@
1
+ module Backup
2
+ module Storage
3
+ class S3
4
+
5
+ # Stores the backup file on the remote server using S3
6
+ def initialize(adapter)
7
+ s3 = Backup::Connection::S3.new(adapter)
8
+ s3.connect
9
+ s3.store
10
+ end
11
+
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,28 @@
1
+ module Backup
2
+ module Storage
3
+ class SCP
4
+
5
+ attr_accessor :user, :password, :ip, :path, :tmp_path, :final_file
6
+
7
+ # Stores the backup file on the remote server using SCP
8
+ def initialize(adapter)
9
+ %w(ip user password path).each do |method|
10
+ send("#{method}=", adapter.procedure.get_storage_configuration.attributes[method])
11
+ end
12
+
13
+ final_file = adapter.final_file
14
+ tmp_path = adapter.tmp_path
15
+
16
+ Net::SSH.start(ip, user, :password => password) do |ssh|
17
+ ssh.exec "mkdir -p #{path}"
18
+ end
19
+
20
+ puts "Storing \"#{final_file}\" to path \"#{path}\" on remote server (#{ip})."
21
+ Net::SCP.start(ip, user, :password => password) do |scp|
22
+ scp.upload! File.join(tmp_path, final_file).gsub('\ ', ' '), path
23
+ end
24
+ end
25
+
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,29 @@
1
+ module Backup
2
+ module Storage
3
+ class SFTP
4
+
5
+ attr_accessor :user, :password, :ip, :path, :tmp_path, :final_file
6
+
7
+ # Stores the backup file on the remote server using SFTP
8
+ def initialize(adapter)
9
+ %w(ip user password path).each do |method|
10
+ send("#{method}=", adapter.procedure.get_storage_configuration.attributes[method])
11
+ end
12
+
13
+ final_file = adapter.final_file
14
+ tmp_path = adapter.tmp_path
15
+
16
+ Net::SFTP.start(ip, user, :password => password) do |sftp|
17
+ begin
18
+ puts "Storing \"#{final_file}\" to path \"#{path}\" on remote server (#{ip})."
19
+ sftp.upload!(File.join(tmp_path, final_file).gsub('\ ', ' '), File.join(path, final_file))
20
+ rescue
21
+ puts "Could not find \"#{path}\" on \"#{ip}\", please ensure this directory exists."
22
+ exit
23
+ end
24
+ end
25
+ end
26
+
27
+ end
28
+ end
29
+ end
data/lib/backup.rb ADDED
@@ -0,0 +1,118 @@
1
+ # Load Gems
2
+ require 'net/ssh'
3
+ require 'net/scp'
4
+ require 'net/ftp'
5
+ require 'net/sftp'
6
+ require 'aws/s3'
7
+ require 'pony'
8
+ require 'hirb'
9
+
10
+ # Load Environments
11
+ require 'backup/environment/base'
12
+ require 'backup/environment/unix'
13
+ require 'backup/environment/rails'
14
+
15
+ # Load Configuration
16
+ require 'backup/configuration/attributes'
17
+ require 'backup/configuration/base'
18
+ require 'backup/configuration/adapter'
19
+ require 'backup/configuration/adapter_options'
20
+ require 'backup/configuration/storage'
21
+ require 'backup/configuration/mail'
22
+ require 'backup/configuration/smtp'
23
+ require 'backup/configuration/helpers'
24
+
25
+ require 'backup/command_helper'
26
+
27
+ # Include the Configuration and Environment Helpers
28
+ include Backup::Configuration::Helpers
29
+ include Backup::Environment::Base
30
+
31
+ # Load either UNIX or RAILS environment configuration
32
+ case current_environment
33
+ when :unix then include Backup::Environment::Unix
34
+ when :rails then include Backup::Environment::Rails
35
+ end
36
+
37
+ # Load configuration
38
+ if File.exist?(File.join(BACKUP_PATH, 'config', 'backup.rb'))
39
+ require File.join(BACKUP_PATH, 'config', 'backup.rb')
40
+ end
41
+
42
+ # Load Mail Notifier
43
+ require 'backup/mail/base'
44
+
45
+ # Set Mail Configuration (extracted from the backup.rb configuration file) inside the Mail Class
46
+ Backup::Mail::Base.setup(@mail_configuration)
47
+
48
+ # Load Adapters
49
+ require 'backup/adapters/base'
50
+ require 'backup/adapters/mysql'
51
+ require 'backup/adapters/sqlite'
52
+ require 'backup/adapters/postgresql'
53
+ require 'backup/adapters/archive'
54
+ require 'backup/adapters/custom'
55
+
56
+ # Load Connectors
57
+ require 'backup/connection/s3'
58
+
59
+ # Load Storage
60
+ require 'backup/storage/s3'
61
+ require 'backup/storage/scp'
62
+ require 'backup/storage/ftp'
63
+ require 'backup/storage/sftp'
64
+ require 'backup/storage/local'
65
+
66
+ # Backup Recorders
67
+ require 'backup/record/base'
68
+ require 'backup/record/s3'
69
+ require 'backup/record/scp'
70
+ require 'backup/record/ftp'
71
+ require 'backup/record/sftp'
72
+ require 'backup/record/local'
73
+
74
+ # Backup Module
75
+ module Backup
76
+ class Setup
77
+
78
+ attr_accessor :trigger, :procedures, :procedure
79
+
80
+ # Sets the Trigger and All Available Procedures.
81
+ # Will not find a specific procedure if the "trigger" argument is set to false.
82
+ def initialize(trigger, procedures)
83
+ self.trigger = trigger
84
+ self.procedures = procedures
85
+ self.procedure = find_triggered_procedure unless trigger.eql?(false)
86
+ end
87
+
88
+ # Initializes one of the few adapters and start the backup process
89
+ def initialize_adapter
90
+ case procedure.adapter_name.to_sym
91
+ when :mysql then Backup::Adapters::MySQL.new trigger, procedure
92
+ when :sqlite then Backup::Adapters::SQLite.new trigger, procedure
93
+ when :postgresql then Backup::Adapters::PostgreSQL.new trigger, procedure
94
+ when :archive then Backup::Adapters::Archive.new trigger, procedure
95
+ when :custom then Backup::Adapters::Custom.new trigger, procedure
96
+ else
97
+ puts "Unknown Adapter: \"#{procedure.adapter_name}\"."
98
+ exit
99
+ end
100
+ end
101
+
102
+ # Scans through all the backup settings and returns the backup setting
103
+ # that was specified in the "trigger" argument.
104
+ # If an non-existing trigger is specified, it will raise an error and display
105
+ # all the available triggers.
106
+ def find_triggered_procedure
107
+ procedures.each do |procedure|
108
+ if procedure.trigger.eql?(trigger)
109
+ return procedure
110
+ end
111
+ end
112
+ available_triggers = procedures.map {|procedure| "- #{procedure.trigger}\n" }
113
+ puts "Could not find a backup procedure with the trigger \"#{trigger}\". \nHere's a list of available triggers:\n#{available_triggers}"
114
+ exit
115
+ end
116
+
117
+ end
118
+ end
data/setup/backup.rb ADDED
@@ -0,0 +1,202 @@
1
+ # Backup Configuration File
2
+ #
3
+ # Use the "backup" block to add backup settings to the configuration file.
4
+ # The argument before the "do" in (backup "argument" do) is called a "trigger".
5
+ # This acts as the identifier for the configuration.
6
+ #
7
+ # In the example below we have a "mysql-backup-s3" trigger for the backup setting.
8
+ # All the configuration is done inside this block. To initialize the backup process for this block,
9
+ # you invoke it using the following command:
10
+ #
11
+ # backup --run mysql-backup-s3
12
+ #
13
+ # You can add as many backup block settings as you want, just be sure every trigger is unique and you can run
14
+ # each of them separately.
15
+ #
16
+ # ADAPTERS
17
+ # - MySQL
18
+ # - PostgreSQL
19
+ # - SQLite
20
+ # - Archive
21
+ # - Custom
22
+ #
23
+ # STORAGE METHODS
24
+ # - S3 (Amazon)
25
+ # - SCP (Remote Server)
26
+ # - FTP (Remote Server)
27
+ # - SFTP (Remote Server)
28
+ # - LOCAL (Local Server)
29
+ #
30
+ # GLOBAL OPTIONS
31
+ # - Keep Backups (keep_backups)
32
+ # - Encrypt With Pasword (encrypt_with_password)
33
+ # - Notify (notify)
34
+ #
35
+ # This is the "decrypt" command for all encrypted backups:
36
+ # sudo backup --decrypt /path/to/encrypted/file
37
+ #
38
+ # Each Backup Setting can contain:
39
+ # - 1 Adapter
40
+ # - 1 Storage Method
41
+ # - Multiple Global Options
42
+ #
43
+ # The combination of these, however, do not matter! So experiment with it.
44
+ #
45
+ # You can also let Backup notify you by email on successfully created backups.
46
+ # - Just uncomment the block of code below (notifier_settings) and fill in your credentials.
47
+ # - Then for set "notify" to "true" in each (backup) block you wish to be notified of.
48
+ #
49
+ # For more information on "Backup", please refer to the wiki on github
50
+ # http://wiki.github.com/meskyanichi/backup/configuration-file
51
+
52
+
53
+ # Notifier
54
+ # Uncomment this if you want to enable notification by email on successful backup runs
55
+ # You will also have to set "notify true" inside each backup block below to enable it for that particular backup
56
+ # notifier_settings do
57
+ #
58
+ # to "example1@gmail.com"
59
+ # from "example2@gmail.com"
60
+ #
61
+ # smtp do
62
+ # host "smtp.gmail.com"
63
+ # port "587"
64
+ # username "example1@gmail.com"
65
+ # password "example1password"
66
+ # authentication "plain"
67
+ # domain "localhost.localdomain"
68
+ # tls true
69
+ # end
70
+ #
71
+ # end
72
+
73
+
74
+ # Initialize with:
75
+ # sudo backup --run mysql-backup-s3
76
+ backup 'mysql-backup-s3' do
77
+
78
+ adapter :mysql do
79
+ user 'user'
80
+ password 'password'
81
+ database 'database'
82
+
83
+ # skip_tables ['table1', 'table2', 'table3']
84
+ #
85
+ # options do
86
+ # host '123.45.678.90'
87
+ # port '80'
88
+ # socket '/tmp/socket.sock'
89
+ # end
90
+ # additional_options '--single-transaction --quick'
91
+ end
92
+
93
+ storage :s3 do
94
+ access_key_id 'access_key_id'
95
+ secret_access_key 'secret_access_key'
96
+ bucket '/bucket/backups/mysql/'
97
+ use_ssl true
98
+ end
99
+
100
+ keep_backups 25
101
+ encrypt_with_password 'password'
102
+ notify false
103
+
104
+ end
105
+
106
+
107
+ # Initialize with:
108
+ # sudo backup --run postgresql-backup-s3
109
+ backup 'postgresql-backup-scp' do
110
+
111
+ adapter :postgresql do
112
+ user 'user'
113
+ database 'database'
114
+
115
+ # skip_tables ['table1', 'table2', 'table3']
116
+
117
+ # options do
118
+ # host '123.45.678.90'
119
+ # port '80'
120
+ # socket '/tmp/socket.sock'
121
+ # end
122
+ # additional_options '--clean --blobs'
123
+ end
124
+
125
+ storage :scp do
126
+ ip 'example.com'
127
+ user 'user'
128
+ password 'password'
129
+ path '/var/backups/postgresql/'
130
+ end
131
+
132
+ keep_backups :all
133
+ encrypt_with_password false
134
+ notify false
135
+
136
+ end
137
+
138
+
139
+ # Initialize with:
140
+ # sudo backup --run archive-backup-ftp
141
+ backup 'archive-backup-ftp' do
142
+
143
+ adapter :archive do
144
+ files ["/path/to/log", "/path/to/db"]
145
+ end
146
+
147
+ storage :ftp do
148
+ ip 'example.com'
149
+ user 'user'
150
+ password 'password'
151
+ path '/var/backups/archive/'
152
+ end
153
+
154
+ keep_backups 10
155
+ encrypt_with_password false
156
+ notify false
157
+
158
+ end
159
+
160
+
161
+ # Initialize with:
162
+ # sudo backup --run custom-backup-sftp
163
+ backup 'custom-backup-sftp' do
164
+
165
+ adapter :custom do
166
+ commands \
167
+ [ "mysqldump [options] [database] > :tmp_path/my_mysql_dump.sql",
168
+ "pg_dump [options] [database] > :tmp_path/my_postgresql_dump.sql",
169
+ "any_other_db_format [options] [database] > :tmp_path/my_any_other_db_format.sql" ]
170
+ end
171
+
172
+ storage :sftp do
173
+ ip 'example.com'
174
+ user 'user'
175
+ password 'password'
176
+ path '/var/backups/custom/'
177
+ end
178
+
179
+ keep_backups :all
180
+ encrypt_with_password 'password'
181
+ notify false
182
+
183
+ end
184
+
185
+
186
+ # Initializ with:
187
+ # sudo backup --run sqlite-backup-local
188
+ backup 'sqlite-backup-local' do
189
+
190
+ adapter :sqlite do
191
+ database "/path/to/database.sqlite3"
192
+ end
193
+
194
+ storage :local do
195
+ path "/path/to/storage/location/"
196
+ end
197
+
198
+ keep_backups :all
199
+ encrypt_with_password false
200
+ notify false
201
+
202
+ end
Binary file
@@ -0,0 +1,35 @@
1
+ require 'backup/configuration/attributes'
2
+
3
+ describe Backup::Configuration::Attributes do
4
+ before(:all) do
5
+ class ConfigurationSample
6
+ extend Backup::Configuration::Attributes
7
+ generate_attributes :file, :username, :password
8
+ end
9
+ @sample = ConfigurationSample.new
10
+ end
11
+
12
+ it "should generate setter methods to attributes" do
13
+ @sample.should respond_to(:file)
14
+ @sample.should respond_to(:username)
15
+ @sample.should respond_to(:password)
16
+ end
17
+
18
+ it "should generate accessor for attributes" do
19
+ @sample.should respond_to(:attributes)
20
+ end
21
+
22
+ it "should store keys of attributes as strings" do
23
+ @sample.file "list.txt"
24
+ @sample.username "jonh"
25
+ @sample.password "secret"
26
+ @sample.attributes.keys.all? {|k| k.is_a?(String)}.should == true
27
+ end
28
+
29
+ it "should store values of attributes in attributes hash" do
30
+ @sample.file "list.txt"
31
+ @sample.attributes.keys.should include('file')
32
+ @sample.attributes['file'].should == "list.txt"
33
+ end
34
+ end
35
+