heroku-mongo-backup 0.1.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.
@@ -0,0 +1,136 @@
1
+ # coding: UTF-8
2
+
3
+ require 'mongo'
4
+ require 'bson'
5
+ require 'json'
6
+ require 'zlib'
7
+ require 'uri'
8
+ require 'yaml'
9
+ require 'rubygems'
10
+ require 's3'
11
+
12
+ module Heroku::Mongo
13
+ class Backup
14
+ def chdir
15
+ Dir.chdir("tmp")
16
+ begin
17
+ Dir.mkdir("dump")
18
+ rescue
19
+ end
20
+ Dir.chdir("dump")
21
+ end
22
+
23
+ def store
24
+ backup = {}
25
+
26
+ @db.collections.each do |col|
27
+ backup['system.indexes.db.name'] = col.db.name if col.name == "system.indexes"
28
+
29
+ records = []
30
+
31
+ col.find().each do |record|
32
+ records << record
33
+ end
34
+
35
+ backup[col.name] = records
36
+ end
37
+
38
+ marshal_dump = Marshal.dump(backup)
39
+
40
+ file = File.new(@file_name, 'w')
41
+ file = Zlib::GzipWriter.new(file)
42
+ file.write marshal_dump
43
+ file.close
44
+ end
45
+
46
+ def load
47
+ file = Zlib::GzipReader.open(@file_name)
48
+ obj = Marshal.load file.read
49
+ file.close
50
+
51
+ obj.each do |col_name, records|
52
+ next if col_name =~ /^system\./
53
+
54
+ @db.drop_collection(col_name)
55
+ dest_col = @db.create_collection(col_name)
56
+
57
+ records.each do |record|
58
+ dest_col.insert record
59
+ end
60
+ end
61
+
62
+ # Load indexes here
63
+ col_name = "system.indexes"
64
+ dest_index_col = @db.collection(col_name)
65
+ obj[col_name].each do |index|
66
+ if index['_id']
67
+ index['ns'] = index['ns'].sub(obj['system.indexes.db.name'], dest_index_col.db.name)
68
+ dest_index_col.insert index
69
+ end
70
+ end
71
+ end
72
+
73
+ def connect
74
+ uri = URI.parse(@url)
75
+ connection = ::Mongo::Connection.new(uri.host, uri.port)
76
+ @db = connection.db(uri.path.gsub(/^\//, ''))
77
+ @db.authenticate(uri.user, uri.password) if uri.user
78
+ end
79
+
80
+ def s3_connect
81
+ bucket = YAML.load_file("config/assets.yml")['s3_bucket']
82
+ access_key_id = ENV['S3_KEY']
83
+ secret_access_key = ENV['S3_SECRET']
84
+
85
+ service = S3::Service.new(:access_key_id => access_key_id,
86
+ :secret_access_key => secret_access_key)
87
+ @bucket = service.buckets.find(bucket)
88
+ end
89
+
90
+ def s3_upload
91
+ object = @bucket.objects.build("backups/#{@file_name}")
92
+ object.content = open(@file_name)
93
+ object.save
94
+ end
95
+
96
+ def s3_download
97
+ open(@file_name, 'w') do |file|
98
+ object = @bucket.objects.find("backups/#{@file_name}")
99
+ file.write object.content
100
+ end
101
+ end
102
+
103
+ def initialize
104
+ # Backup settings
105
+ @file_name = Time.now.strftime("%Y-%m-%d_%H-%M-%S.gz")
106
+
107
+ # MongoDB config
108
+ local_db_name = YAML.load_file("config/mongoid.yml")['development']['database']
109
+
110
+ development_uri = "mongodb://localhost:27017/#{local_db_name}"
111
+ production_uri = YAML.load_file("config/mongoid.yml")['production']['uri']
112
+
113
+ #@url = development_uri
114
+ @url = production_uri
115
+
116
+ puts "Using databased: #{@url}"
117
+
118
+ self.connect
119
+ self.s3_connect
120
+ end
121
+
122
+ def backup
123
+ self.chdir
124
+ self.store
125
+ self.s3_upload
126
+ end
127
+
128
+ def restore file_name
129
+ @file_name = file_name
130
+
131
+ self.chdir
132
+ self.s3_download
133
+ self.load
134
+ end
135
+ end
136
+ end
@@ -0,0 +1,17 @@
1
+ # coding: UTF-8
2
+
3
+ namespace :mongo do
4
+ desc "Mongo backup and restore commands.\n\tBackup: rake mongo:backup\n\tRestore: rake mongo:restore FILE=<backup-file.gz>"
5
+
6
+ task :backup => [:environment] do
7
+ Heroku::Mongo::Backup.new.backup
8
+ end
9
+
10
+ task :restore => [:environment] do
11
+ if ENV['FILE']
12
+ Heroku::Mongo::Backup.new.restore ENV['FILE']
13
+ else
14
+ puts "Please provide backup file to restore from. Thanks!"
15
+ end
16
+ end
17
+ end
metadata ADDED
@@ -0,0 +1,68 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: heroku-mongo-backup
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Alex Kraves
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2011-09-13 00:00:00.000000000Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: rspec
16
+ requirement: &70318711197760 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :development
23
+ prerelease: false
24
+ version_requirements: *70318711197760
25
+ - !ruby/object:Gem::Dependency
26
+ name: mocha
27
+ requirement: &70318711197280 !ruby/object:Gem::Requirement
28
+ none: false
29
+ requirements:
30
+ - - ! '>='
31
+ - !ruby/object:Gem::Version
32
+ version: '0'
33
+ type: :development
34
+ prerelease: false
35
+ version_requirements: *70318711197280
36
+ description: Rake task for backing up mongo database on heroku and push it to S3.
37
+ email: mail@alexkravets.com
38
+ executables: []
39
+ extensions: []
40
+ extra_rdoc_files: []
41
+ files:
42
+ - lib/heroku_mongo_backup.rb
43
+ - lib/tasks/heroku_mongo_backup.rake
44
+ homepage: https://github.com/alexkravets/heroku-mongo-backup
45
+ licenses: []
46
+ post_install_message:
47
+ rdoc_options: []
48
+ require_paths:
49
+ - lib
50
+ required_ruby_version: !ruby/object:Gem::Requirement
51
+ none: false
52
+ requirements:
53
+ - - ! '>='
54
+ - !ruby/object:Gem::Version
55
+ version: '0'
56
+ required_rubygems_version: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ! '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ requirements: []
63
+ rubyforge_project: nowarning
64
+ rubygems_version: 1.8.6
65
+ signing_key:
66
+ specification_version: 3
67
+ summary: Rake task for backing up mongo database on heroku and push it to S3.
68
+ test_files: []