backup 1.0.0 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -2,9 +2,7 @@
2
2
 
3
3
  == What is "Backup"?
4
4
 
5
- "Backup" is a RubyGem written for Rails to (easily) handle backing up your database files and assets to either Amazon S3, or any other server using SSH.
6
- You barely have to get your hands dirty! Backup provides you with 2 (easily) configurable .yml files. These two files are the only ones you will need to use to configure
7
- all your backups.
5
+ Backup is a RubyGem, written for Ruby on Rails. It's main purpose is to Backup any files to Amazon S3 or any remotely accessible server through SSH (SCP). It supports database and regular file backups. On top of that, it's extremely easy to set up. Backup will provide a generator script that will place all necessary files inside your Rails application. Two of which, are “yaml” configuration files. Using just these two files to configure a backup for database formats such as a MySQL, SQLite3 or any Assets folder. Setting up “Backup” takes only about a minute or two!
8
6
 
9
7
 
10
8
  === Backup makes use of two storage methods:
data/Rakefile CHANGED
@@ -19,7 +19,9 @@ begin
19
19
  gem.email = "meskyan@gmail.com"
20
20
  gem.homepage = "http://github.com/meskyanichi/backup"
21
21
  gem.authors = ["meskyanichi"]
22
- gem.add_dependency "aws-s3"
22
+ gem.add_dependency "aws-s3", ">= 0.6.2"
23
+ gem.add_dependency "net-ssh", ">= 2.0.15"
24
+ gem.add_dependency "net-scp", ">= 1.0.2"
23
25
  # gem.files.include 'generators/**/*'
24
26
  # gem.files.include 'lib/**/*'
25
27
  end
data/VERSION CHANGED
@@ -1 +1 @@
1
- 1.0.0
1
+ 1.1.0
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{backup}
8
- s.version = "1.0.0"
8
+ s.version = "1.1.0"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["meskyanichi"]
12
- s.date = %q{2009-10-07}
12
+ s.date = %q{2009-10-08}
13
13
  s.description = %q{
14
14
  “Backup” is a RubyGem, written for Ruby on Rails. It's main purpose is to Backup any
15
15
  files to Amazon S3 or any remotely accessible server through SSH (SCP). It supports database
@@ -32,22 +32,26 @@ Gem::Specification.new do |s|
32
32
  "Rakefile",
33
33
  "VERSION",
34
34
  "backup.gemspec",
35
- "generators/backup_tasks/backup_tasks_generator.rb",
36
- "generators/backup_tasks/templates/config.rake",
37
- "generators/backup_tasks/templates/s3.rake",
38
- "generators/backup_tasks/templates/s3.yml",
39
- "generators/backup_tasks/templates/ssh.rake",
40
- "generators/backup_tasks/templates/ssh.yml",
35
+ "generators/backup_files/backup_files_generator.rb",
36
+ "generators/backup_files/templates/backup.sqlite3",
37
+ "generators/backup_files/templates/config.rake",
38
+ "generators/backup_files/templates/db.rake",
39
+ "generators/backup_files/templates/s3.rake",
40
+ "generators/backup_files/templates/s3.yml",
41
+ "generators/backup_files/templates/ssh.rake",
42
+ "generators/backup_files/templates/ssh.yml",
41
43
  "lib/backup.rb",
42
- "lib/backup/assets.rb",
44
+ "lib/backup/adapter/assets.rb",
45
+ "lib/backup/adapter/custom.rb",
46
+ "lib/backup/adapter/mysql.rb",
47
+ "lib/backup/adapter/sqlite3.rb",
48
+ "lib/backup/backup_record/s3.rb",
49
+ "lib/backup/backup_record/ssh.rb",
43
50
  "lib/backup/base.rb",
44
51
  "lib/backup/connection/base.rb",
45
52
  "lib/backup/connection/s3.rb",
46
53
  "lib/backup/connection/ssh.rb",
47
- "lib/backup/custom.rb",
48
54
  "lib/backup/encrypt.rb",
49
- "lib/backup/mysql.rb",
50
- "lib/backup/sqlite3.rb",
51
55
  "lib/backup/transfer/base.rb",
52
56
  "lib/backup/transfer/s3.rb",
53
57
  "lib/backup/transfer/ssh.rb"
@@ -63,11 +67,17 @@ Gem::Specification.new do |s|
63
67
  s.specification_version = 3
64
68
 
65
69
  if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
66
- s.add_runtime_dependency(%q<aws-s3>, [">= 0"])
70
+ s.add_runtime_dependency(%q<aws-s3>, [">= 0.6.2"])
71
+ s.add_runtime_dependency(%q<net-ssh>, [">= 2.0.15"])
72
+ s.add_runtime_dependency(%q<net-scp>, [">= 1.0.2"])
67
73
  else
68
- s.add_dependency(%q<aws-s3>, [">= 0"])
74
+ s.add_dependency(%q<aws-s3>, [">= 0.6.2"])
75
+ s.add_dependency(%q<net-ssh>, [">= 2.0.15"])
76
+ s.add_dependency(%q<net-scp>, [">= 1.0.2"])
69
77
  end
70
78
  else
71
- s.add_dependency(%q<aws-s3>, [">= 0"])
79
+ s.add_dependency(%q<aws-s3>, [">= 0.6.2"])
80
+ s.add_dependency(%q<net-ssh>, [">= 2.0.15"])
81
+ s.add_dependency(%q<net-scp>, [">= 1.0.2"])
72
82
  end
73
83
  end
@@ -1,4 +1,4 @@
1
- class BackupTasksGenerator < Rails::Generator::Base
1
+ class BackupFilesGenerator < Rails::Generator::Base
2
2
 
3
3
  # This method gets initialized when the generator gets run.
4
4
  # It will receive an array of arguments inside @args
@@ -15,17 +15,22 @@ class BackupTasksGenerator < Rails::Generator::Base
15
15
  record do |m|
16
16
 
17
17
  # Generate the Rake Tasks
18
- m.directory "lib/tasks/"
18
+ m.directory "lib/tasks"
19
19
  m.directory "lib/tasks/backup"
20
20
  m.file "config.rake", "lib/tasks/backup/config.rake"
21
21
  m.file "s3.rake", "lib/tasks/backup/s3.rake"
22
22
  m.file "ssh.rake", "lib/tasks/backup/ssh.rake"
23
+ m.file "db.rake", "lib/tasks/backup/db.rake"
23
24
 
24
25
  # Generate the YAML files
25
26
  m.directory "config/backup"
26
27
  m.file "s3.yml", "config/backup/s3.yml"
27
28
  m.file "ssh.yml", "config/backup/ssh.yml"
28
29
 
30
+ # Generates the backup.sqlite3 database
31
+ m.directory "db"
32
+ m.file "backup.sqlite3", "db/backup.sqlite3"
33
+
29
34
  end
30
35
  end
31
36
 
@@ -0,0 +1,49 @@
1
+ namespace :backup do
2
+ namespace :db do
3
+ namespace :truncate do
4
+
5
+ desc 'Truncates all the Backup database records; Physical files WILL NOT be deleted.'
6
+ task :all => :environment do
7
+ puts "Truncating All!"
8
+ Backup::BackupRecord::S3.destroy_all
9
+ Backup::BackupRecord::SSH.destroy_all
10
+ end
11
+
12
+ desc 'Truncates the S3 Backup database records; Physical files WILL NOT be deleted from S3.'
13
+ task :s3 => :environment do
14
+ puts "Truncating S3 Backup database records!"
15
+ Backup::BackupRecord::S3.destroy_all
16
+ end
17
+
18
+ desc 'Truncates the SHH database records; Physical files WILL NOT be deleted from remote server.'
19
+ task :ssh => :environment do
20
+ puts "Truncating SSH database records!"
21
+ Backup::BackupRecord::SSH.destroy_all
22
+ end
23
+
24
+ end
25
+
26
+ =begin
27
+ namespace :destroy do
28
+
29
+ desc 'Destroys all Backup database records; Physical files WILL be deleted as well.'
30
+ task :all => :environment do
31
+ Backup::BackupRecord::S3.destroy_all_backups
32
+ Backup::BackupRecord::SSH.destroy_all_backups
33
+ end
34
+
35
+ desc 'Destroys S3 Backup database records; Physical files WILL be deleted as well.'
36
+ task :s3 => :s3_config do
37
+ Backup::BackupRecord::S3.destroy_all_backups
38
+ end
39
+
40
+ desc 'Destroys SSH Backup database records; Physical files WILL be deleted as well.'
41
+ task :ssh => :ssh_config do
42
+ Backup::BackupRecord::SSH.destroy_all_backups
43
+ end
44
+
45
+ end
46
+ =end
47
+
48
+ end
49
+ end
@@ -11,14 +11,16 @@ namespace :backup do
11
11
  desc 'Makes a backup from a MySQL database and transfers it to Amazon S3.'
12
12
  task :mysql => :s3_config do
13
13
  @config = @config['mysql']
14
- Backup::Mysql.new({
14
+ Backup::Adapter::Mysql.new({
15
+ :adapter => 'mysql',
15
16
  :mysql => {
16
17
  :user => @config['mysql_config']['user'],
17
18
  :password => @config['mysql_config']['password'],
18
19
  :database => @config['mysql_config']['database']
19
20
  },
20
21
 
21
- :encrypt => @config['encrypt'],
22
+ :encrypt => @config['encrypt'],
23
+ :keep_backups => @config['keep_backups'],
22
24
 
23
25
  :use => :s3,
24
26
  :s3 => {
@@ -39,11 +41,13 @@ namespace :backup do
39
41
  desc 'Makes a backup from a SQLite3 database and transfers it to Amazon S3.'
40
42
  task :sqlite3 => :s3_config do
41
43
  @config = @config['sqlite3']
42
- Backup::Sqlite3.new({
43
- :file => @config['file'],
44
- :path => @config['path'],
45
- :encrypt => @config['encrypt'],
46
-
44
+ Backup::Adapter::Sqlite3.new({
45
+ :adapter => 'sqlite3',
46
+ :file => @config['file'],
47
+ :path => @config['path'],
48
+ :encrypt => @config['encrypt'],
49
+ :keep_backups => @config['keep_backups'],
50
+
47
51
  :use => :s3,
48
52
  :s3 => {
49
53
  :access_key_id => @config['s3']['access_key_id'],
@@ -63,9 +67,11 @@ namespace :backup do
63
67
  desc 'Makes a backup from Assets and transfers it to Amazon S3.'
64
68
  task :assets => :s3_config do
65
69
  @config = @config['assets']
66
- Backup::Assets.new({
67
- :path => @config['path'],
68
- :encrypt => @config['encrypt'],
70
+ Backup::Adapter::Assets.new({
71
+ :adapter => 'assets',
72
+ :path => @config['path'],
73
+ :encrypt => @config['encrypt'],
74
+ :keep_backups => @config['keep_backups'],
69
75
 
70
76
  :use => :s3,
71
77
  :s3 => {
@@ -113,11 +119,13 @@ namespace :backup do
113
119
  desc 'Makes a backup from a Custom database and transfers it to Amazon S3.'
114
120
  task :custom => :s3_config do
115
121
  @config = @config['custom']
116
- Backup::Custom.new({
117
- :file => @config['file'],
118
- :path => @config['path'],
119
- :command => @config['command'],
120
- :encrypt => @config['encrypt'],
122
+ Backup::Adapter::Custom.new({
123
+ :adapter => 'custom',
124
+ :file => @config['file'],
125
+ :path => @config['path'],
126
+ :command => @config['command'],
127
+ :encrypt => @config['encrypt'],
128
+ :keep_backups => @config['keep_backups'],
121
129
 
122
130
  :use => :s3,
123
131
  :s3 => {
@@ -28,6 +28,35 @@
28
28
  # For handling this, I recommend using the javan-whenever gem
29
29
  #
30
30
  # See here: http://github.com/javan/whenever
31
+ #
32
+
33
+
34
+ # Global Options
35
+ #
36
+ # - encrypt (optional!)
37
+ #
38
+ # What "encrypt" does is encrypt your backup with the given password
39
+ # Example:
40
+ # encrypt: this_is_my_password
41
+ #
42
+ # This will encrypt the backup file with the password: this_is_my_password
43
+ # NOTE: To "decrypt" an encrypted file later on, use the following command:
44
+ # openssl enc -des-cbc -d -in encrypted_file -out decrypted_file
45
+ #
46
+ #
47
+ # - keep_backups (optional!)
48
+ #
49
+ # what "keep_backups" does is it ensures that there won't be more than the specified
50
+ # amount of backups present on the storage location (S3 or any remotely accessible server)
51
+ # Example:
52
+ # keep_backups: 10
53
+ #
54
+ # This will make sure there won't be more than 10 backups on the server at a time.
55
+ # When the 11th backup is pushed to for example Amazon S3, it will delete the oldest
56
+ # backup. Why would you want this? To avoid S3 from being expensive and otherwise
57
+ # to not overload your remote server's harddisk and practically fload it.
58
+
59
+
31
60
 
32
61
 
33
62
  # MySQL Adapter
@@ -37,12 +66,13 @@ mysql:
37
66
  mysql_config:
38
67
  user: root
39
68
  password: ''
40
- database: my_database
69
+ database: foobar
41
70
  s3:
42
71
  access_key_id: my_access_key_id
43
72
  secret_access_key: my_secret_access_key
44
73
  bucket: my_bucket
45
- #encrypt: my_secret_password # Uncomment me if you want to encrypt the backup
74
+ #encrypt: my_secret_password # Uncomment me if you want this functionality
75
+ #keep_backups: 25 # Uncomment me if you want this functionality
46
76
 
47
77
 
48
78
  # SQLite3 Adapter
@@ -55,7 +85,8 @@ sqlite3:
55
85
  access_key_id: my_access_key_id
56
86
  secret_access_key: my_secret_access_key
57
87
  bucket: my_bucket
58
- #encrypt: my_secret_password # Uncomment me if you want to encrypt the backup
88
+ #encrypt: my_secret_password # Uncomment me if you want this functionality
89
+ #keep_backups: 25 # Uncomment me if you want this functionality
59
90
 
60
91
 
61
92
  # Asset Adapter
@@ -67,8 +98,8 @@ assets:
67
98
  access_key_id: my_access_key_id
68
99
  secret_access_key: my_secret_access_key
69
100
  bucket: my_bucket
70
- #encrypt: my_secret_password # Uncomment me if you want to encrypt the backup
71
-
101
+ #encrypt: my_secret_password # Uncomment me if you want this functionality
102
+ #keep_backups: 25 # Uncomment me if you want this functionality
72
103
 
73
104
  # Custom Adapter
74
105
  # To run this adapter, execute the following rake task:
@@ -85,4 +116,5 @@ custom:
85
116
  access_key_id: my_access_key_id
86
117
  secret_access_key: my_secret_access_key
87
118
  bucket: my_bucket
88
- #encrypt: my_secret_password # Uncomment me if you want to encrypt the backup
119
+ #encrypt: my_secret_password # Uncomment me if you want this functionality
120
+ #keep_backups: 25 # Uncomment me if you want this functionality
@@ -9,14 +9,16 @@ namespace :backup do
9
9
  desc 'Makes a backup from a MySQL database and transfers it through SSH (SCP).'
10
10
  task :mysql => :ssh_config do
11
11
  @config = @config['mysql']
12
- Backup::Mysql.new({
12
+ Backup::Adapter::Mysql.new({
13
+ :adapter => 'mysql',
13
14
  :mysql => {
14
15
  :user => @config['mysql_config']['user'],
15
16
  :password => @config['mysql_config']['password'],
16
17
  :database => @config['mysql_config']['database']
17
18
  },
18
19
 
19
- :encrypt => @config['encrypt'],
20
+ :encrypt => @config['encrypt'],
21
+ :keep_backups => @config['keep_backups'],
20
22
 
21
23
  :use => :ssh,
22
24
  :ssh => {
@@ -36,10 +38,12 @@ namespace :backup do
36
38
  desc 'Makes a backup from a SQLite3 database and transfers it through SSH (SCP).'
37
39
  task :sqlite3 => :ssh_config do
38
40
  @config = @config['sqlite3']
39
- Backup::Sqlite3.new({
40
- :file => @config['file'],
41
- :path => @config['path'],
42
- :encrypt => @config['encrypt'],
41
+ Backup::Adapter::Sqlite3.new({
42
+ :adapter => 'sqlite3',
43
+ :file => @config['file'],
44
+ :path => @config['path'],
45
+ :encrypt => @config['encrypt'],
46
+ :keep_backups => @config['keep_backups'],
43
47
 
44
48
  :use => :ssh,
45
49
  :ssh => {
@@ -58,9 +62,11 @@ namespace :backup do
58
62
  desc 'Makes a backup from Assets and transfers it through SSH (SCP).'
59
63
  task :assets => :ssh_config do
60
64
  @config = @config['assets']
61
- Backup::Assets.new({
62
- :path => @config['path'],
63
- :encrypt => @config['encrypt'],
65
+ Backup::Adapter::Assets.new({
66
+ :adapter => 'assets',
67
+ :path => @config['path'],
68
+ :encrypt => @config['encrypt'],
69
+ :keep_backups => @config['keep_backups'],
64
70
 
65
71
  :use => :ssh,
66
72
  :ssh => {
@@ -108,11 +114,13 @@ namespace :backup do
108
114
  desc 'Makes a backup from a Custom database and transfers it through SSH (SCP).'
109
115
  task :custom => :ssh_config do
110
116
  @config = @config['custom']
111
- Backup::Custom.new({
112
- :file => @config['file'],
113
- :path => @config['path'],
114
- :command => @config['command'],
115
- :encrypt => @config['encrypt'],
117
+ Backup::Adapter::Custom.new({
118
+ :adapter => 'custom',
119
+ :file => @config['file'],
120
+ :path => @config['path'],
121
+ :command => @config['command'],
122
+ :encrypt => @config['encrypt'],
123
+ :keep_backups => @config['keep_backups'],
116
124
 
117
125
  :use => :ssh,
118
126
  :ssh => {
@@ -30,6 +30,34 @@
30
30
  # See here: http://github.com/javan/whenever
31
31
 
32
32
 
33
+ # Global Options
34
+ #
35
+ # - encrypt (optional!)
36
+ #
37
+ # What "encrypt" does is encrypt your backup with the given password
38
+ # Example:
39
+ # encrypt: this_is_my_password
40
+ #
41
+ # This will encrypt the backup file with the password: this_is_my_password
42
+ # NOTE: To "decrypt" an encrypted file later on, use the following command:
43
+ # openssl enc -des-cbc -d -in encrypted_file -out decrypted_file
44
+ #
45
+ #
46
+ # - keep_backups (optional!)
47
+ #
48
+ # what "keep_backups" does is it ensures that there won't be more than the specified
49
+ # amount of backups present on the storage location (S3 or any remotely accessible server)
50
+ # Example:
51
+ # keep_backups: 10
52
+ #
53
+ # This will make sure there won't be more than 10 backups on the server at a time.
54
+ # When the 11th backup is pushed to for example Amazon S3, it will delete the oldest
55
+ # backup. Why would you want this? To avoid S3 from being expensive and otherwise
56
+ # to not overload your remote server's harddisk and practically fload it.
57
+
58
+
59
+
60
+
33
61
  # MySQL Adapter
34
62
  # To run this adapter, execute the following rake task:
35
63
  # rake backup:ssh:mysql
@@ -42,7 +70,8 @@ mysql:
42
70
  user: root
43
71
  ip: my-domain.com
44
72
  path: '/var/backups'
45
- #encrypt: my_secret_password # Uncomment me if you want to encrypt the backup
73
+ #encrypt: my_secret_password # Uncomment me if you want this functionality
74
+ #keep_backups: 25 # Uncomment me if you want this functionality
46
75
 
47
76
 
48
77
  # SQLite3 Adapter
@@ -55,8 +84,8 @@ sqlite3:
55
84
  user: root
56
85
  ip: my-domain.com
57
86
  path: '/var/backups'
58
- #encrypt: my_secret_password # Uncomment me if you want to encrypt the backup
59
-
87
+ #encrypt: my_secret_password # Uncomment me if you want this functionality
88
+ #keep_backups: 25 # Uncomment me if you want this functionality
60
89
 
61
90
  # Asset Adapter
62
91
  # To run this adapter, execute the following rake task:
@@ -67,7 +96,8 @@ assets:
67
96
  user: root
68
97
  ip: my-domain.com
69
98
  path: '/var/backups'
70
- #encrypt: my_secret_password # Uncomment me if you want to encrypt the backup
99
+ #encrypt: my_secret_password # Uncomment me if you want this functionality
100
+ #keep_backups: 25 # Uncomment me if you want this functionality
71
101
 
72
102
 
73
103
  # Custom Adapter
@@ -79,10 +109,11 @@ custom:
79
109
  - 'foobar1.sql'
80
110
  - 'foobar2.sql'
81
111
  command:
82
- - 'mysqldump --quick -u root --password="" foobar1 > :rails_root/db/foobar1.sql'
83
- - 'mysqldump --quick -u root --password="" foobar2 > :rails_root/db/foobar2.sql'
112
+ - 'mysqldump --quick -u root --password="" foobar > :rails_root/db/foobar1.sql'
113
+ - 'mysqldump --quick -u root --password="" foobar > :rails_root/db/foobar2.sql'
84
114
  ssh:
85
115
  user: root
86
116
  ip: my-domain.com
87
117
  path: '/var/backups'
88
- #encrypt: my_secret_password # Uncomment me if you want to encrypt the backup
118
+ #encrypt: my_secret_password # Uncomment me if you want this functionality
119
+ #keep_backups: 25 # Uncomment me if you want this functionality
@@ -1,15 +1,16 @@
1
1
  require 'backup/base'
2
- require 'backup/sqlite3'
3
- require 'backup/mysql'
4
- require 'backup/assets'
5
- require 'backup/custom'
6
2
  require 'backup/encrypt'
3
+ require 'backup/adapter/sqlite3'
4
+ require 'backup/adapter/mysql'
5
+ require 'backup/adapter/assets'
6
+ require 'backup/adapter/custom'
7
7
  require 'backup/transfer/base'
8
8
  require 'backup/transfer/s3'
9
9
  require 'backup/transfer/ssh'
10
10
  require 'backup/connection/base'
11
11
  require 'backup/connection/s3'
12
12
  require 'backup/connection/ssh'
13
+ require 'backup/backup_record/s3'
13
14
 
14
15
  module Backup
15
16
  end
@@ -0,0 +1,54 @@
1
+ module Backup
2
+ module Adapter
3
+ class Assets < Backup::Base
4
+
5
+ def initialize(options = {})
6
+ super(default_options.merge(options))
7
+ setup_paths("assets/#{self.class.name.downcase.gsub('::','-')}", 'tar.gz')
8
+ end
9
+
10
+ # Initialize the process
11
+ # Executing multiple processes
12
+ #
13
+ # - Archive
14
+ # Archives the specified folder to a .tar
15
+ # - Compress
16
+ # Compresses the .tar file using Gzip
17
+ # - Encrypt
18
+ # Encrypts the backup file
19
+ # - Transfer
20
+ # Initializes the transfer to either S3 or using SSH
21
+ # - Records
22
+ # Records the Backup Data to the Backup SQLite3 database
23
+ # - Remove Temp Files
24
+ # Removes temporary files after the process is complete
25
+ def run
26
+ archive
27
+ compress
28
+ encrypt
29
+ transfer
30
+ record
31
+ remove_temp_files
32
+ end
33
+
34
+ private
35
+
36
+ # Archives the assets into a .tar file and stores it
37
+ # inside the "Backup Path"
38
+ def archive
39
+ %x{ tar -cf #{File.join(options[:backup_path], options[:backup_file])} #{options[:path]} }
40
+ end
41
+
42
+ # Compresses the .tar file to .tar.gz and removes the old .tar file
43
+ def compress
44
+ %x{ gzip --best #{File.join(options[:backup_path], options[:backup_file])} }
45
+ end
46
+
47
+ # Set default options
48
+ def default_options
49
+ { :path => "#{RAILS_ROOT}/public/assets", :file => "assets" }
50
+ end
51
+
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,88 @@
1
+ module Backup
2
+ module Adapter
3
+ class Custom < Backup::Base
4
+
5
+ def initialize(options = {})
6
+ super(default_options.merge(options))
7
+ setup_paths("db/#{self.class.name.downcase.gsub('::','-')}", options[:file].is_a?(Array) ? 'tar.gz' : 'gz')
8
+ end
9
+
10
+ # Initialize the process
11
+ # Executing multiple processes
12
+ #
13
+ # - Command
14
+ # Executes a command from a user to generate a SQL dump
15
+ # - Archive
16
+ # Archives the specified folder to a .tar
17
+ # - Compress
18
+ # Compresses the .tar file using Gzip
19
+ # - Encrypt
20
+ # Encrypts the backup file
21
+ # - Transfer
22
+ # Initializes the transfer to either S3 or using SSH
23
+ # - Records
24
+ # Records the Backup Data to the Backup SQLite3 database
25
+ # - Remove Temp Files
26
+ # Removes temporary files after the process is complete
27
+ # - Remove Original File
28
+ # Removes the user generated sql files (unless the user specifies he wants to keep them)
29
+ def run
30
+ command
31
+ archive
32
+ compress
33
+ encrypt
34
+ transfer
35
+ record
36
+ remove_temp_files
37
+ remove_original_file
38
+ end
39
+
40
+ private
41
+
42
+ # Allows a user to insert one or more commands to be executed
43
+ # before the actual archive, compress and transferring processes.
44
+ # The command takes either a String for a single command, and an Array for multiple commands.
45
+ def command
46
+ if options[:command].is_a?(Array)
47
+ options[:command].each do |command|
48
+ %x{ #{command} }
49
+ end
50
+ else
51
+ %x{ #{options[:command]} }
52
+ end
53
+ end
54
+
55
+ # Archives the assets into a .tar file and stores it
56
+ # inside the "Backup Path"
57
+ def archive
58
+ if options[:file].is_a?(Array)
59
+ files = options[:file].map {|file| File.join(options[:path], file)}
60
+ %x{ tar -cf #{File.join(options[:backup_path], options[:backup_file])} #{files.join(' ')} }
61
+ else
62
+ %x{ tar -cf #{File.join(options[:backup_path], options[:backup_file])} #{File.join(options[:path], options[:file])} }
63
+ end
64
+ end
65
+
66
+ # If the user has bundled a couple of files to a .tar (by using an Array for the :file attribute)
67
+ # then it compresses the .tar file to .tar.gz and removes the old .tar file
68
+ # If the user has only a single file, it will be read out and a new file will be generated
69
+ # The old (single) file will remain until the process is complete, unless the user specifies otherwise.
70
+ def compress
71
+ if options[:file].is_a?(Array)
72
+ %x{ gzip --best #{File.join(options[:backup_path], options[:backup_file])} }
73
+ else
74
+ %x{ gzip -cv #{File.join(options[:path], options[:file])} --best > #{File.join(options[:backup_path], options[:backup_file])} }
75
+ end
76
+ end
77
+
78
+ # Set default options
79
+ def default_options
80
+ { :path => "",
81
+ :file => "",
82
+ :command => "",
83
+ :keep_original_files => false }
84
+ end
85
+
86
+ end
87
+ end
88
+ end
@@ -0,0 +1,62 @@
1
+ module Backup
2
+ module Adapter
3
+ class Mysql < Backup::Base
4
+
5
+ def initialize(options = {})
6
+ super(default_options.merge(options))
7
+ setup_paths("db/#{self.class.name.downcase.gsub('::','-')}", :gz)
8
+ end
9
+
10
+ # Initialize the process
11
+ # Executing multiple processes
12
+ #
13
+ # - Make MySQL Dump
14
+ # Creates a MySQL dump based on the parameters provided by the user
15
+ # - Compress
16
+ # Compresses the .tar file using Gzip
17
+ # - Encrypt
18
+ # Encrypts the backup file
19
+ # - Transfer
20
+ # Initializes the transfer to either S3 or using SSH
21
+ # - Records
22
+ # Records the Backup Data to the Backup SQLite3 database
23
+ # - Remove Temp Files
24
+ # Removes temporary files after the process is complete
25
+ def run
26
+ make_mysql_dump
27
+ compress
28
+ encrypt
29
+ transfer
30
+ record
31
+ remove_temp_files
32
+ end
33
+
34
+ private
35
+
36
+ # Compresses the MySQL dump file and stores the compressed version inside the tmp/backups folder.
37
+ def compress
38
+ %x{ gzip -cv #{File.join(options[:path], options[:file])} --best > #{File.join(options[:backup_path], options[:backup_file])} }
39
+ end
40
+
41
+ # This will generate a MySQL dump based on the options the user passed in.
42
+ # The MySQL dump will be placed (by default) in the config/db directory so it can be found
43
+ # by the compressor.
44
+ def make_mysql_dump
45
+ # => /usr/local/mysql/bin/mysqldump on Mac OS X 10.6
46
+ %x{ mysqldump --quick -u #{options[:mysql][:user]} --password='#{options[:mysql][:password]}' #{options[:mysql][:database]} > #{File.join(options[:path], options[:file])} }
47
+ end
48
+
49
+ # Set default options
50
+ def default_options
51
+ {:path => "#{RAILS_ROOT}/tmp/backups/db/#{self.class.name.downcase.gsub('::','-')}",
52
+ :file => "production.sql",
53
+ :mysql => {
54
+ :user => "",
55
+ :password => "",
56
+ :database => ""
57
+ }}
58
+ end
59
+
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,46 @@
1
+ module Backup
2
+ module Adapter
3
+ class Sqlite3 < Backup::Base
4
+
5
+ def initialize(options = {})
6
+ super(default_options.merge(options))
7
+ setup_paths("db/#{self.class.name.downcase.gsub('::','-')}", :gz)
8
+ end
9
+
10
+ # Initialize the process
11
+ # Executing multiple processes
12
+ #
13
+ # - Compress
14
+ # Compresses the .tar file using Gzip
15
+ # - Encrypt
16
+ # Encrypts the backup file
17
+ # - Transfer
18
+ # Initializes the transfer to either S3 or using SSH
19
+ # - Records
20
+ # Records the Backup Data to the Backup SQLite3 database
21
+ # - Remove Temp Files
22
+ # Removes temporary files after the process is complete
23
+ def run
24
+ compress
25
+ encrypt
26
+ transfer
27
+ record
28
+ remove_temp_files
29
+ end
30
+
31
+ private
32
+
33
+ # Compresses the SQLite3file and stores the compressed version inside the tmp/backups folder.
34
+ def compress
35
+ %x{ gzip -cv #{File.join(options[:path], options[:file])} --best > #{File.join(options[:backup_path], options[:backup_file])} }
36
+ end
37
+
38
+ # Set default options
39
+ def default_options
40
+ { :path => "#{RAILS_ROOT}/db",
41
+ :file => "production.sqlite3" }
42
+ end
43
+
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,81 @@
1
+ require 'aws/s3'
2
+
3
+ module Backup
4
+ module BackupRecord
5
+ class S3 < ActiveRecord::Base
6
+
7
+ # Establishes a connection with the SQLite3
8
+ # local database to avoid conflict with users
9
+ # Production database.
10
+ establish_connection(
11
+ :adapter => "sqlite3",
12
+ :database => "db/backup.sqlite3",
13
+ :pool => 5,
14
+ :timeout => 5000 )
15
+
16
+ # Scopes
17
+ default_scope :order => 'created_at desc'
18
+
19
+ # Callbacks
20
+ after_save :destroy_old_backups
21
+
22
+ # Attributes
23
+ attr_accessor :options, :keep_backups
24
+
25
+ # Receives the options hash and stores it
26
+ # Sets the S3 values
27
+ def set_options(options)
28
+ self.options = options
29
+ self.backup_file = options[:backup_file]
30
+ self.bucket = options[:s3][:bucket]
31
+ self.keep_backups = options[:keep_backups]
32
+ self.adapter = options[:adapter]
33
+ end
34
+
35
+ def self.destroy_all_backups(options)
36
+ s3 = Backup::Connection::S3.new(options)
37
+ s3.connect
38
+ backups = Backup::BackupRecord::S3.all
39
+ backups.each do |backup|
40
+ puts "Destroying backup: #{backup.backup_file}.."
41
+ s3.destroy(backup.backup_file, backup.bucket)
42
+ backup.destroy
43
+ end
44
+ puts "All S3 Backups Destroyed!"
45
+ end
46
+
47
+ private
48
+
49
+ # Destroys backups when the backup limit has been reached
50
+ # This is determined by the "keep_backups:" parameter
51
+ # First all backups will be fetched.
52
+ def destroy_old_backups
53
+ if keep_backups.is_a?(Integer)
54
+ backups = Backup::BackupRecord::S3.all(:conditions => {:adapter => adapter})
55
+ backups_to_destroy = Array.new
56
+ backups.each_with_index do |backup, index|
57
+ if index >= keep_backups then
58
+ backups_to_destroy << backup
59
+ end
60
+ end
61
+
62
+ if backups_to_destroy
63
+ # Create a new Amazon S3 Object
64
+ s3 = Backup::Connection::S3.new(options)
65
+
66
+ # Connect to Amazon S3 with provided credentials
67
+ s3.connect
68
+
69
+ # Loop through all backups that should be destroyed and remove them from S3.
70
+ backups_to_destroy.each do |backup|
71
+ puts "Destroying old backup: #{backup.backup_file}.."
72
+ s3.destroy(backup.backup_file, backup.bucket)
73
+ backup.destroy
74
+ end
75
+ end
76
+ end
77
+ end
78
+
79
+ end
80
+ end
81
+ end
@@ -0,0 +1,68 @@
1
+ require 'net/ssh'
2
+
3
+ module Backup
4
+ module BackupRecord
5
+ class SSH < ActiveRecord::Base
6
+
7
+ # Establishes a connection with the SQLite3
8
+ # local database to avoid conflict with users
9
+ # Production database.
10
+ establish_connection(
11
+ :adapter => "sqlite3",
12
+ :database => "db/backup.sqlite3",
13
+ :pool => 5,
14
+ :timeout => 5000 )
15
+
16
+ # Scopes
17
+ default_scope :order => 'created_at desc'
18
+
19
+ # Callbacks
20
+ after_save :destroy_old_backups
21
+
22
+ # Attributes
23
+ attr_accessor :options, :keep_backups, :ip, :user
24
+
25
+ # Receives the options hash and stores it
26
+ # Sets the S3 values
27
+ def set_options(options)
28
+ self.options = options
29
+ self.backup_file = options[:backup_file]
30
+ self.backup_path = options[:ssh][:path]
31
+ self.keep_backups = options[:keep_backups]
32
+ self.adapter = options[:adapter]
33
+ self.ip = options[:ssh][:ip]
34
+ self.user = options[:ssh][:user]
35
+ end
36
+
37
+ private
38
+
39
+ # Destroys backups when the backup limit has been reached
40
+ # This is determined by the "keep_backups:" parameter
41
+ # First all backups will be fetched.
42
+ def destroy_old_backups
43
+ if keep_backups.is_a?(Integer)
44
+ backups = Backup::BackupRecord::SSH.all(:conditions => {:adapter => adapter})
45
+ backups_to_destroy = Array.new
46
+ backups.each_with_index do |backup, index|
47
+ if index >= keep_backups then
48
+ backups_to_destroy << backup
49
+ end
50
+ end
51
+
52
+ if backups_to_destroy
53
+ # Establish a connection with the remote server through SSH
54
+ Net::SSH.start(ip, user) do |ssh|
55
+ # Loop through all backups that should be destroyed and remove them from S3.
56
+ backups_to_destroy.each do |backup|
57
+ puts "Destroying old backup: #{backup.backup_file}.."
58
+ ssh.exec("rm #{File.join(backup.backup_path, backup.backup_file)}")
59
+ backup.destroy
60
+ end
61
+ end
62
+ end
63
+ end
64
+ end
65
+
66
+ end
67
+ end
68
+ end
@@ -38,6 +38,24 @@ module Backup
38
38
  end
39
39
  end
40
40
 
41
+ # Records a backup to the "backup.sqlite3" database
42
+ # Will destroy any old backups that exceed the amount of
43
+ # backups that are allowed to be stored on either S3 or any
44
+ # remote server through SSH.
45
+ def record
46
+ case options[:use]
47
+ when :s3
48
+ backup = Backup::BackupRecord::S3.new
49
+ backup.set_options(options)
50
+ backup.save
51
+
52
+ when :ssh
53
+ backup = Backup::BackupRecord::SSH.new
54
+ backup.set_options(options)
55
+ backup.save
56
+ end
57
+ end
58
+
41
59
  # Encrypts the backup file
42
60
  # Only if the encrypt option is specified inside the .yml config file
43
61
  # Otherwise, the encryption will be not be executed.
@@ -38,6 +38,13 @@ module Backup
38
38
  options[:s3][:bucket] )
39
39
  end
40
40
 
41
+ # Destroys file from a bucket on Amazon S3
42
+ def destroy(backup_file, bucket)
43
+ object.delete(
44
+ backup_file,
45
+ bucket )
46
+ end
47
+
41
48
  end
42
49
  end
43
50
  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.0.0
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - meskyanichi
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-10-07 00:00:00 +02:00
12
+ date: 2009-10-08 00:00:00 +02:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -20,7 +20,27 @@ dependencies:
20
20
  requirements:
21
21
  - - ">="
22
22
  - !ruby/object:Gem::Version
23
- version: "0"
23
+ version: 0.6.2
24
+ version:
25
+ - !ruby/object:Gem::Dependency
26
+ name: net-ssh
27
+ type: :runtime
28
+ version_requirement:
29
+ version_requirements: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: 2.0.15
34
+ version:
35
+ - !ruby/object:Gem::Dependency
36
+ name: net-scp
37
+ type: :runtime
38
+ version_requirement:
39
+ version_requirements: !ruby/object:Gem::Requirement
40
+ requirements:
41
+ - - ">="
42
+ - !ruby/object:Gem::Version
43
+ version: 1.0.2
24
44
  version:
25
45
  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 "
26
46
  email: meskyan@gmail.com
@@ -39,22 +59,26 @@ files:
39
59
  - Rakefile
40
60
  - VERSION
41
61
  - backup.gemspec
42
- - generators/backup_tasks/backup_tasks_generator.rb
43
- - generators/backup_tasks/templates/config.rake
44
- - generators/backup_tasks/templates/s3.rake
45
- - generators/backup_tasks/templates/s3.yml
46
- - generators/backup_tasks/templates/ssh.rake
47
- - generators/backup_tasks/templates/ssh.yml
62
+ - generators/backup_files/backup_files_generator.rb
63
+ - generators/backup_files/templates/backup.sqlite3
64
+ - generators/backup_files/templates/config.rake
65
+ - generators/backup_files/templates/db.rake
66
+ - generators/backup_files/templates/s3.rake
67
+ - generators/backup_files/templates/s3.yml
68
+ - generators/backup_files/templates/ssh.rake
69
+ - generators/backup_files/templates/ssh.yml
48
70
  - lib/backup.rb
49
- - lib/backup/assets.rb
71
+ - lib/backup/adapter/assets.rb
72
+ - lib/backup/adapter/custom.rb
73
+ - lib/backup/adapter/mysql.rb
74
+ - lib/backup/adapter/sqlite3.rb
75
+ - lib/backup/backup_record/s3.rb
76
+ - lib/backup/backup_record/ssh.rb
50
77
  - lib/backup/base.rb
51
78
  - lib/backup/connection/base.rb
52
79
  - lib/backup/connection/s3.rb
53
80
  - lib/backup/connection/ssh.rb
54
- - lib/backup/custom.rb
55
81
  - lib/backup/encrypt.rb
56
- - lib/backup/mysql.rb
57
- - lib/backup/sqlite3.rb
58
82
  - lib/backup/transfer/base.rb
59
83
  - lib/backup/transfer/s3.rb
60
84
  - lib/backup/transfer/ssh.rb
@@ -1,49 +0,0 @@
1
- module Backup
2
- class Assets < Backup::Base
3
-
4
- def initialize(options = {})
5
- super(default_options.merge(options))
6
- setup_paths("assets/#{self.class.name.downcase.gsub('::','-')}", 'tar.gz')
7
- end
8
-
9
- # Initialize the process
10
- # Executing multiple processes
11
- #
12
- # - Archive
13
- # Archives the specified folder to a .tar
14
- # - Compress
15
- # Compresses the .tar file using Gzip
16
- # - Encrypt
17
- # Encrypts the backup file
18
- # - Transfer
19
- # Initializes the transfer to either S3 or using SSH
20
- # - Remove Temp Files
21
- # Removes temporary files after the process is complete
22
- def run
23
- archive
24
- compress
25
- encrypt
26
- transfer
27
- remove_temp_files
28
- end
29
-
30
- private
31
-
32
- # Archives the assets into a .tar file and stores it
33
- # inside the "Backup Path"
34
- def archive
35
- %x{ tar -cf #{File.join(options[:backup_path], options[:backup_file])} #{options[:path]} }
36
- end
37
-
38
- # Compresses the .tar file to .tar.gz and removes the old .tar file
39
- def compress
40
- %x{ gzip --best #{File.join(options[:backup_path], options[:backup_file])} }
41
- end
42
-
43
- # Set default options
44
- def default_options
45
- { :path => "#{RAILS_ROOT}/public/assets", :file => "assets" }
46
- end
47
-
48
- end
49
- end
@@ -1,83 +0,0 @@
1
- module Backup
2
- class Custom < Backup::Base
3
-
4
- def initialize(options = {})
5
- super(default_options.merge(options))
6
- setup_paths("db/#{self.class.name.downcase.gsub('::','-')}", options[:file].is_a?(Array) ? 'tar.gz' : 'gz')
7
- end
8
-
9
- # Initialize the process
10
- # Executing multiple processes
11
- #
12
- # - Command
13
- # Executes a command from a user to generate a SQL dump
14
- # - Archive
15
- # Archives the specified folder to a .tar
16
- # - Compress
17
- # Compresses the .tar file using Gzip
18
- # - Encrypt
19
- # Encrypts the backup file
20
- # - Transfer
21
- # Initializes the transfer to either S3 or using SSH
22
- # - Remove Temp Files
23
- # Removes temporary files after the process is complete
24
- # - Remove Original File
25
- # Removes the user generated sql files (unless the user specifies he wants to keep them)
26
- def run
27
- command
28
- archive
29
- compress
30
- encrypt
31
- transfer
32
- remove_temp_files
33
- remove_original_file
34
- end
35
-
36
- private
37
-
38
- # Allows a user to insert one or more commands to be executed
39
- # before the actual archive, compress and transferring processes.
40
- # The command takes either a String for a single command, and an Array for multiple commands.
41
- def command
42
- if options[:command].is_a?(Array)
43
- options[:command].each do |command|
44
- %x{ #{command} }
45
- end
46
- else
47
- %x{ #{options[:command]} }
48
- end
49
- end
50
-
51
- # Archives the assets into a .tar file and stores it
52
- # inside the "Backup Path"
53
- def archive
54
- if options[:file].is_a?(Array)
55
- files = options[:file].map {|file| File.join(options[:path], file)}
56
- %x{ tar -cf #{File.join(options[:backup_path], options[:backup_file])} #{files.join(' ')} }
57
- else
58
- %x{ tar -cf #{File.join(options[:backup_path], options[:backup_file])} #{File.join(options[:path], options[:file])} }
59
- end
60
- end
61
-
62
- # If the user has bundled a couple of files to a .tar (by using an Array for the :file attribute)
63
- # then it compresses the .tar file to .tar.gz and removes the old .tar file
64
- # If the user has only a single file, it will be read out and a new file will be generated
65
- # The old (single) file will remain until the process is complete, unless the user specifies otherwise.
66
- def compress
67
- if options[:file].is_a?(Array)
68
- %x{ gzip --best #{File.join(options[:backup_path], options[:backup_file])} }
69
- else
70
- %x{ gzip -cv #{File.join(options[:path], options[:file])} --best > #{File.join(options[:backup_path], options[:backup_file])} }
71
- end
72
- end
73
-
74
- # Set default options
75
- def default_options
76
- { :path => "",
77
- :file => "",
78
- :command => "",
79
- :keep_original_files => false }
80
- end
81
-
82
- end
83
- end
@@ -1,57 +0,0 @@
1
- module Backup
2
- class Mysql < Backup::Base
3
-
4
- def initialize(options = {})
5
- super(default_options.merge(options))
6
- setup_paths("db/#{self.class.name.downcase.gsub('::','-')}", :gz)
7
- end
8
-
9
- # Initialize the process
10
- # Executing multiple processes
11
- #
12
- # - Make MySQL Dump
13
- # Creates a MySQL dump based on the parameters provided by the user
14
- # - Compress
15
- # Compresses the .tar file using Gzip
16
- # - Encrypt
17
- # Encrypts the backup file
18
- # - Transfer
19
- # Initializes the transfer to either S3 or using SSH
20
- # - Remove Temp Files
21
- # Removes temporary files after the process is complete
22
- def run
23
- make_mysql_dump
24
- compress
25
- encrypt
26
- transfer
27
- remove_temp_files
28
- end
29
-
30
- private
31
-
32
- # Compresses the MySQL dump file and stores the compressed version inside the tmp/backups folder.
33
- def compress
34
- %x{ gzip -cv #{File.join(options[:path], options[:file])} --best > #{File.join(options[:backup_path], options[:backup_file])} }
35
- end
36
-
37
- # This will generate a MySQL dump based on the options the user passed in.
38
- # The MySQL dump will be placed (by default) in the config/db directory so it can be found
39
- # by the compressor.
40
- def make_mysql_dump
41
- # => /usr/local/mysql/bin/mysqldump on Mac OS X 10.6
42
- %x{ mysqldump --quick -u #{options[:mysql][:user]} --password='#{options[:mysql][:password]}' #{options[:mysql][:database]} > #{File.join(options[:path], options[:file])} }
43
- end
44
-
45
- # Set default options
46
- def default_options
47
- {:path => "#{RAILS_ROOT}/tmp/backups/db/#{self.class.name.downcase.gsub('::','-')}",
48
- :file => "production.sql",
49
- :mysql => {
50
- :user => "",
51
- :password => "",
52
- :database => ""
53
- }}
54
- end
55
-
56
- end
57
- end
@@ -1,41 +0,0 @@
1
- module Backup
2
- class Sqlite3 < Backup::Base
3
-
4
- def initialize(options = {})
5
- super(default_options.merge(options))
6
- setup_paths("db/#{self.class.name.downcase.gsub('::','-')}", :gz)
7
- end
8
-
9
- # Initialize the process
10
- # Executing multiple processes
11
- #
12
- # - Compress
13
- # Compresses the .tar file using Gzip
14
- # - Encrypt
15
- # Encrypts the backup file
16
- # - Transfer
17
- # Initializes the transfer to either S3 or using SSH
18
- # - Remove Temp Files
19
- # Removes temporary files after the process is complete
20
- def run
21
- compress
22
- encrypt
23
- transfer
24
- remove_temp_files
25
- end
26
-
27
- private
28
-
29
- # Compresses the SQLite3file and stores the compressed version inside the tmp/backups folder.
30
- def compress
31
- %x{ gzip -cv #{File.join(options[:path], options[:file])} --best > #{File.join(options[:backup_path], options[:backup_file])} }
32
- end
33
-
34
- # Set default options
35
- def default_options
36
- { :path => "#{RAILS_ROOT}/db",
37
- :file => "production.sqlite3" }
38
- end
39
-
40
- end
41
- end