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.
- data/lib/heroku_mongo_backup.rb +136 -0
- data/lib/tasks/heroku_mongo_backup.rake +17 -0
- metadata +68 -0
@@ -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: []
|