backup 1.3.4 → 2.0.0

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 (44) hide show
  1. data/README.rdoc +121 -53
  2. data/Rakefile +3 -8
  3. data/VERSION +1 -1
  4. data/backup.gemspec +20 -34
  5. data/generators/backup/backup_generator.rb +31 -0
  6. data/generators/backup/templates/config/backup.rb +60 -0
  7. data/generators/backup/templates/migrations/create_backup_tables.rb +24 -0
  8. data/generators/backup/templates/tasks/backup.rake +42 -0
  9. data/lib/backup.rb +64 -12
  10. data/lib/backup/adapters/archive.rb +53 -0
  11. data/lib/backup/adapters/base.rb +65 -0
  12. data/lib/backup/adapters/mysql.rb +48 -0
  13. data/lib/backup/configuration/adapter.rb +17 -0
  14. data/lib/backup/configuration/base.rb +38 -0
  15. data/lib/backup/configuration/helpers.rb +12 -0
  16. data/lib/backup/configuration/storage.rb +17 -0
  17. data/lib/backup/connection/s3.rb +28 -13
  18. data/lib/backup/record/s3.rb +90 -0
  19. data/lib/backup/record/scp.rb +92 -0
  20. data/lib/backup/storage/s3.rb +14 -0
  21. data/lib/backup/storage/scp.rb +28 -0
  22. metadata +18 -35
  23. data/generators/backup_files/backup_files_generator.rb +0 -72
  24. data/generators/backup_files/templates/backup.sqlite3 +0 -0
  25. data/generators/backup_files/templates/config.rake +0 -20
  26. data/generators/backup_files/templates/db.rake +0 -62
  27. data/generators/backup_files/templates/s3.rake +0 -231
  28. data/generators/backup_files/templates/s3.yml +0 -120
  29. data/generators/backup_files/templates/setup.rake +0 -28
  30. data/generators/backup_files/templates/ssh.rake +0 -226
  31. data/generators/backup_files/templates/ssh.yml +0 -119
  32. data/lib/backup/adapter/assets.rb +0 -57
  33. data/lib/backup/adapter/custom.rb +0 -91
  34. data/lib/backup/adapter/mysql.rb +0 -65
  35. data/lib/backup/adapter/sqlite3.rb +0 -49
  36. data/lib/backup/backup_record/s3.rb +0 -90
  37. data/lib/backup/backup_record/ssh.rb +0 -90
  38. data/lib/backup/base.rb +0 -92
  39. data/lib/backup/connection/base.rb +0 -13
  40. data/lib/backup/connection/ssh.rb +0 -19
  41. data/lib/backup/encrypt.rb +0 -18
  42. data/lib/backup/transfer/base.rb +0 -13
  43. data/lib/backup/transfer/s3.rb +0 -36
  44. data/lib/backup/transfer/ssh.rb +0 -30
@@ -0,0 +1,90 @@
1
+ module Backup
2
+ module Record
3
+ class S3 < ActiveRecord::Base
4
+
5
+ # Establishes a connection with the SQLite3
6
+ # local database to avoid conflict with users
7
+ # Production database.
8
+ # establish_connection(
9
+ # :adapter => "sqlite3",
10
+ # :database => "db/backup.sqlite3",
11
+ # :pool => 5,
12
+ # :timeout => 5000 )
13
+
14
+ set_table_name 'backup_s3'
15
+
16
+ # Scopes
17
+ default_scope :order => 'created_at desc'
18
+
19
+ # Callbacks
20
+ after_save :clean_backups
21
+
22
+ # Attributes
23
+ attr_accessor :adapter_config, :keep_backups
24
+
25
+ # Receives the options hash and stores it
26
+ # Sets the S3 values
27
+ def load_adapter(adapter)
28
+ self.adapter_config = adapter
29
+ self.trigger = adapter.procedure.trigger
30
+ self.adapter = adapter.procedure.adapter_name
31
+ self.filename = adapter.final_file
32
+ self.bucket = adapter.procedure.get_storage_configuration.attributes['bucket']
33
+ self.keep_backups = adapter.procedure.attributes['keep_backups']
34
+ end
35
+
36
+ # Destroys all backups for the specified trigger from Amazon S3
37
+ def self.destroy_all_backups(procedure, trigger)
38
+ backups = Backup::Record::S3.all(:conditions => {:trigger => trigger})
39
+ unless backups.empty?
40
+ s3 = Backup::Connection::S3.new
41
+ s3.static_initialize(procedure)
42
+ s3.connect
43
+ backups.each do |backup|
44
+ puts "\nDestroying backup \"#{backup.filename}\" from bucket \"#{backup.bucket}\"."
45
+ s3.destroy(backup.filename, backup.bucket)
46
+ backup.destroy
47
+ end
48
+ puts "\nAll \"#{trigger}\" backups destroyed.\n\n"
49
+ end
50
+ end
51
+
52
+ private
53
+
54
+ # Maintains the backup file amount on S3
55
+ # This is invoked after a successful record save
56
+ # This deletes the oldest files when the backup limit has been exceeded
57
+ def clean_backups
58
+ if keep_backups.is_a?(Integer)
59
+ backups = Backup::Record::S3.all(:conditions => {:trigger => trigger})
60
+ backups_to_destroy = Array.new
61
+ backups.each_with_index do |backup, index|
62
+ if index >= keep_backups then
63
+ backups_to_destroy << backup
64
+ end
65
+ end
66
+
67
+ unless backups_to_destroy.empty?
68
+
69
+ # Create a new Amazon S3 Object
70
+ s3 = Backup::Connection::S3.new(adapter_config)
71
+
72
+ # Connect to Amazon S3 with provided credentials
73
+ s3.connect
74
+
75
+ # Loop through all backups that should be destroyed and remove them from S3.
76
+ backups_to_destroy.each do |backup|
77
+ puts "\nDestroying backup \"#{backup.filename}\" from bucket \"#{backup.bucket}\"."
78
+ s3.destroy(backup.filename, backup.bucket)
79
+ backup.destroy
80
+ end
81
+
82
+ puts "\nBackup storage for \"#{trigger}\" is limited to #{keep_backups} backups."
83
+ puts "\nThe #{keep_backups} most recent backups are now stored on S3.\n\n"
84
+ end
85
+ end
86
+ end
87
+
88
+ end
89
+ end
90
+ end
@@ -0,0 +1,92 @@
1
+ module Backup
2
+ module Record
3
+ class SCP < ActiveRecord::Base
4
+
5
+ # Establishes a connection with the SQLite3
6
+ # local database to avoid conflict with users
7
+ # Production database.
8
+ # establish_connection(
9
+ # :adapter => "sqlite3",
10
+ # :database => "db/backup.sqlite3",
11
+ # :pool => 5,
12
+ # :timeout => 5000 )
13
+
14
+ set_table_name 'backup_scp'
15
+
16
+ # Scopes
17
+ default_scope :order => 'created_at desc'
18
+
19
+ # Callbacks
20
+ after_save :clean_backups
21
+
22
+ # Attributes
23
+ attr_accessor :adapter_config, :keep_backups, :ip, :user, :password
24
+
25
+ # Receives the options hash and stores it
26
+ # Sets the SCP values
27
+ def load_adapter(adapter)
28
+ self.adapter_config = adapter
29
+ self.trigger = adapter.procedure.trigger
30
+ self.adapter = adapter.procedure.adapter_name
31
+ self.filename = adapter.final_file
32
+ self.keep_backups = adapter.procedure.attributes['keep_backups']
33
+
34
+ %w(ip user password path).each do |method|
35
+ send(:"#{method}=", adapter.procedure.get_storage_configuration.attributes[method])
36
+ end
37
+ end
38
+
39
+ # Destroys all backups for the specified trigger from Remote Server (SCP)
40
+ def self.destroy_all_backups(procedure, trigger)
41
+ backups = Backup::Record::SCP.all(:conditions => {:trigger => trigger})
42
+ unless backups.empty?
43
+ ip = procedure.get_storage_configuration.attributes['ip']
44
+ user = procedure.get_storage_configuration.attributes['user']
45
+ password = procedure.get_storage_configuration.attributes['password']
46
+
47
+ Net::SSH.start(ip, user, :password => password) do |ssh|
48
+ backups.each do |backup|
49
+ puts "\nDestroying backup \"#{backup.filename}\" from path \"#{backup.path}\"."
50
+ ssh.exec("rm #{File.join(backup.path, backup.filename)}")
51
+ backup.destroy
52
+ end
53
+ end
54
+ puts "\nAll \"#{trigger}\" backups destroyed.\n\n"
55
+ end
56
+ end
57
+
58
+ private
59
+
60
+ # Maintains the backup file amount on the remote server
61
+ # This is invoked after a successful record save
62
+ # This deletes the oldest files when the backup limit has been exceeded
63
+ def clean_backups
64
+ if keep_backups.is_a?(Integer)
65
+ backups = Backup::Record::SCP.all(:conditions => {:trigger => trigger})
66
+ backups_to_destroy = Array.new
67
+ backups.each_with_index do |backup, index|
68
+ if index >= keep_backups then
69
+ backups_to_destroy << backup
70
+ end
71
+ end
72
+
73
+ unless backups_to_destroy.empty?
74
+
75
+ Net::SSH.start(ip, user, :password => password) do |ssh|
76
+ backups_to_destroy.each do |backup|
77
+ puts "\nDestroying backup \"#{backup.filename}\" from path \"#{backup.path}\"."
78
+ ssh.exec("rm #{File.join(backup.path, backup.filename)}")
79
+ backup.destroy
80
+ end
81
+ end
82
+
83
+ puts "\nBackup storage for \"#{trigger}\" is limited to #{keep_backups} backups."
84
+ puts "\nThe #{keep_backups} most recent backups are now stored on the remote server.\n\n"
85
+
86
+ end
87
+ end
88
+ end
89
+
90
+ end
91
+ end
92
+ end
@@ -0,0 +1,14 @@
1
+ module Backup
2
+ module Storage
3
+ class S3
4
+
5
+ # Stores the 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 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
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: backup
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.3.4
4
+ version: 2.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Michael van Rooijen
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-11-08 00:00:00 +01:00
12
+ date: 2009-12-01 00:00:00 +01:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -42,17 +42,7 @@ dependencies:
42
42
  - !ruby/object:Gem::Version
43
43
  version: 1.0.2
44
44
  version:
45
- - !ruby/object:Gem::Dependency
46
- name: sqlite3-ruby
47
- type: :runtime
48
- version_requirement:
49
- version_requirements: !ruby/object:Gem::Requirement
50
- requirements:
51
- - - ">="
52
- - !ruby/object:Gem::Version
53
- version: 1.2.5
54
- version:
55
- description: "\n \xE2\x80\x9CBackup\xE2\x80\x9D is a RubyGem, written for Ruby on Rails. It's main purpose is to Backup any\n files to Amazon S3 or any remotely accessible server through SSH (SCP). It supports database\n and regular file backups. On top of that, it's extremely easy to set up. Backup will provide\n a generator script that will place all necessary files inside your Rails application.\n Two of which, are \xE2\x80\x9Cyaml\xE2\x80\x9D configuration files. Using just these two files to configure a\n backup for database formats such as a MySQL, SQLite3 or any Assets folder.\n Setting up \xE2\x80\x9CBackup\xE2\x80\x9D takes only about a minute or two!\n "
45
+ description: "\n Backup is a Ruby Gem, written specifically for Ruby on Rails applications. This gem offers a quick and easy way\n to configure and run backups of your MySQL database (soon PostgreSQL and possibly more) and Archives (any files or folders)\n to \"Amazon S3\" or \"any remotely accessible server using SCP\". Backup handles: Compression, Archiving, Encryption and Backup Cleaning.\n "
56
46
  email: meskyan@gmail.com
57
47
  executables: []
58
48
 
@@ -69,30 +59,23 @@ files:
69
59
  - Rakefile
70
60
  - VERSION
71
61
  - backup.gemspec
72
- - generators/backup_files/backup_files_generator.rb
73
- - generators/backup_files/templates/backup.sqlite3
74
- - generators/backup_files/templates/config.rake
75
- - generators/backup_files/templates/db.rake
76
- - generators/backup_files/templates/s3.rake
77
- - generators/backup_files/templates/s3.yml
78
- - generators/backup_files/templates/setup.rake
79
- - generators/backup_files/templates/ssh.rake
80
- - generators/backup_files/templates/ssh.yml
62
+ - generators/backup/backup_generator.rb
63
+ - generators/backup/templates/config/backup.rb
64
+ - generators/backup/templates/migrations/create_backup_tables.rb
65
+ - generators/backup/templates/tasks/backup.rake
81
66
  - lib/backup.rb
82
- - lib/backup/adapter/assets.rb
83
- - lib/backup/adapter/custom.rb
84
- - lib/backup/adapter/mysql.rb
85
- - lib/backup/adapter/sqlite3.rb
86
- - lib/backup/backup_record/s3.rb
87
- - lib/backup/backup_record/ssh.rb
88
- - lib/backup/base.rb
89
- - lib/backup/connection/base.rb
67
+ - lib/backup/adapters/archive.rb
68
+ - lib/backup/adapters/base.rb
69
+ - lib/backup/adapters/mysql.rb
70
+ - lib/backup/configuration/adapter.rb
71
+ - lib/backup/configuration/base.rb
72
+ - lib/backup/configuration/helpers.rb
73
+ - lib/backup/configuration/storage.rb
90
74
  - lib/backup/connection/s3.rb
91
- - lib/backup/connection/ssh.rb
92
- - lib/backup/encrypt.rb
93
- - lib/backup/transfer/base.rb
94
- - lib/backup/transfer/s3.rb
95
- - lib/backup/transfer/ssh.rb
75
+ - lib/backup/record/s3.rb
76
+ - lib/backup/record/scp.rb
77
+ - lib/backup/storage/s3.rb
78
+ - lib/backup/storage/scp.rb
96
79
  has_rdoc: true
97
80
  homepage: ""
98
81
  licenses: []
@@ -1,72 +0,0 @@
1
- class BackupFilesGenerator < Rails::Generator::Base
2
-
3
- # This method gets initialized when the generator gets run.
4
- # It will receive an array of arguments inside @args
5
- def initialize(runtime_args, runtime_options = {})
6
- super
7
- extract_args
8
- set_defaults
9
- confirm_input
10
- end
11
-
12
- # Processes the file generation/templating
13
- # This will automatically be run after the initialize method
14
- def manifest
15
- record do |m|
16
-
17
- # Generate the Rake Tasks
18
- m.directory "lib/tasks"
19
- m.directory "lib/tasks/backup"
20
- m.directory "lib/tasks/backup/files"
21
- m.file "config.rake", "lib/tasks/backup/config.rake"
22
- m.file "s3.rake", "lib/tasks/backup/s3.rake"
23
- m.file "ssh.rake", "lib/tasks/backup/ssh.rake"
24
- m.file "db.rake", "lib/tasks/backup/db.rake"
25
- m.file "setup.rake", "lib/tasks/backup/setup.rake"
26
- m.file "backup.sqlite3", "lib/tasks/backup/files/backup.sqlite3"
27
-
28
- # Generate the YAML files
29
- m.directory "config/backup"
30
- m.file "s3.yml", "config/backup/s3.yml"
31
- m.file "ssh.yml", "config/backup/ssh.yml"
32
-
33
- # Generates the backup.sqlite3 database
34
- m.directory "db"
35
- m.file "backup.sqlite3", "db/backup.sqlite3"
36
-
37
- end
38
- end
39
-
40
- # Creates a new Hash Object containing the user input
41
- # The user input will be available through @input and input
42
- def extract_args
43
- @input = Hash.new
44
- @args.each do |arg|
45
- if arg.include?(":") then
46
- @input[:"#{arg.slice(0, arg.index(":"))}"] = arg.slice((arg.index(":") + 1)..-1)
47
- end
48
- end
49
- end
50
-
51
- # Input Method that's available inside the generated templates
52
- # because instance variable are not available, so we access them through methods
53
- def input
54
- @input
55
- end
56
-
57
- # Sets defaults for user input when left blank by the user
58
- # for each parameter
59
- def set_defaults
60
- end
61
-
62
- # Confirms whether the model and attachment arguments were passed in
63
- # Raises an error if not
64
- def confirm_input
65
- end
66
-
67
- private
68
-
69
- def input_error
70
- end
71
-
72
- end
@@ -1,20 +0,0 @@
1
- # Opens and Reads the Backup YAML File from the RAILS_ROOT/config/backup path
2
- # Replaces all the :rails_root tokens with the actual RAILS_ROOT path
3
- # Returns the content of the file in YAML format
4
- def read_backup_yaml_file(config_file)
5
- YAML.load File.open(File.join(RAILS_ROOT, 'config', 'backup', config_file), 'r').read.gsub(/:rails_root/, RAILS_ROOT)
6
- end
7
-
8
- namespace :backup do
9
-
10
- task :s3_config => :environment do
11
- @config = read_backup_yaml_file('s3.yml')
12
- @adapters = ['mysql', 'sqlite3', 'assets', 'custom']
13
- end
14
-
15
- task :ssh_config => :environment do
16
- @config = read_backup_yaml_file('ssh.yml')
17
- @adapters = ['mysql', 'sqlite3', 'assets', 'custom']
18
- end
19
-
20
- end
@@ -1,62 +0,0 @@
1
- namespace :backup do
2
- namespace :db do
3
- namespace :truncate do
4
-
5
- desc 'Truncates the S3 Backup database records; Physical files WILL NOT be deleted from S3.'
6
- task :s3 => :environment do
7
- puts "Truncating S3 Backup database records!"
8
- Backup::BackupRecord::S3.destroy_all
9
- end
10
-
11
- desc 'Truncates the SHH database records; Physical files WILL NOT be deleted from remote server.'
12
- task :ssh => :environment do
13
- puts "Truncating SSH database records!"
14
- Backup::BackupRecord::SSH.destroy_all
15
- end
16
-
17
- end
18
-
19
-
20
- namespace :destroy do
21
-
22
- desc 'Destroys S3 Backup database records; Physical files WILL be deleted as well.'
23
- task :s3 => :s3_config do
24
- puts "Removing all backups from S3.."
25
- @adapters.each do |adapter|
26
- if @config[adapter]
27
- unless @config[adapter].is_a?(Array)
28
- puts "\n\n-- Processing #{adapter} backups --"
29
- Backup::BackupRecord::S3.destroy_all_backups(adapter, @config[adapter], 0)
30
- else
31
- puts "\n\n-- Processing #{adapter} backups --"
32
- @config[adapter].each_with_index do |config, index|
33
- Backup::BackupRecord::S3.destroy_all_backups(adapter, config, index)
34
- end
35
- end
36
- end
37
- end
38
- puts "\n\nAll S3 backups destroyed!\n\n"
39
- end
40
-
41
- desc 'Destroys SSH Backup database records; Physical files WILL be deleted as well.'
42
- task :ssh => :ssh_config do
43
- puts "Removing all backups from remote server through SSH.."
44
- @adapters.each do |adapter|
45
- if @config[adapter]
46
- unless @config[adapter].is_a?(Array)
47
- puts "\n\n-- Processing #{adapter} backups --"
48
- Backup::BackupRecord::SSH.destroy_all_backups(adapter, @config[adapter], 0)
49
- else
50
- puts "\n\n-- Processing #{adapter} backups --"
51
- @config[adapter].each_with_index do |config, index|
52
- Backup::BackupRecord::SSH.destroy_all_backups(adapter, config, index)
53
- end
54
- end
55
- end
56
- end
57
- puts "\n\nAll backups from remote server destroyed!\n\n"
58
- end
59
-
60
- end
61
- end
62
- end