Class: HerokuMongoBackup::Backup

Inherits:
Object
  • Object
show all
Defined in:
lib/heroku-mongo-backup.rb

Instance Method Summary collapse

Constructor Details

#initialize(connect = true) ⇒ Backup

Returns a new instance of Backup.



152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
# File 'lib/heroku-mongo-backup.rb', line 152

def initialize connect = true
  @file_name = Time.now.strftime("%Y-%m-%d_%H-%M-%S.gz")
  
  if( ['production', 'staging'].include?(ENV['RAILS_ENV'] || ENV['RACK_ENV']) )

    #config_template = ERB.new(IO.read("config/mongoid.yml"))
    #uri = YAML.load(config_template.result)['production']['uri']
    uri = ENV['MONGO_URL']

    if uri.nil?
      uri = ENV['MONGOHQ_URL']
    end
    if uri.nil?
      uri = ENV['MONGOLAB_URI']
    end          
  
  else
    mongoid_config  = YAML.load_file("config/mongoid.yml")
    config = {}
    defaults        = mongoid_config['defaults']
    dev_config      = mongoid_config['development']

    config.merge!(defaults) unless defaults.nil?
    config.merge!(dev_config)

    host            = config['host']
    port            = config['port']
    database        = config['database']
    uri = "mongodb://#{host}:#{port}/#{database}"

    if uri == 'mongodb://:/' # new mongoid version 3.x
      mongoid_config  = YAML.load_file("config/mongoid.yml")
      dev_config      = mongoid_config['development']['sessions']['default']
      host_port       = dev_config['hosts'].first
      database        = dev_config['database']
      uri = "mongodb://#{host_port}/#{database}"
    end
  end
  
  @url = uri
  
  puts "Using database: #{@url}"
  
  self.db_connect

  if connect
    if ENV['UPLOAD_TYPE'] == 'ftp'
      self.ftp_connect
    else
      self.s3_connect
    end
  end
end

Instance Method Details

#backup(files_number_to_leave = 0) ⇒ Object



206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
# File 'lib/heroku-mongo-backup.rb', line 206

def backup files_number_to_leave=0
  self.chdir    
  self.store

  if ENV['UPLOAD_TYPE'] == 'ftp'
    self.ftp_upload
    @ftp.close
  else
    self.s3_upload
  end

  if files_number_to_leave > 0
    HerokuMongoBackup::remove_old_backup_files(@bucket, files_number_to_leave)
  end
end

#chdirObject



24
25
26
27
28
29
30
31
# File 'lib/heroku-mongo-backup.rb', line 24

def chdir
  Dir.chdir("/tmp")
  begin
    Dir.mkdir("dump")
  rescue
  end
  Dir.chdir("dump")
end

#db_connectObject



84
85
86
87
88
89
# File 'lib/heroku-mongo-backup.rb', line 84

def db_connect
  uri = URI.parse(@url)
  connection = ::Mongo::Connection.new(uri.host, uri.port)
  @db = connection.db(uri.path.gsub(/^\//, ''))
  @db.authenticate(uri.user, uri.password) if uri.user
end

#ftp_connectObject



91
92
93
94
95
# File 'lib/heroku-mongo-backup.rb', line 91

def ftp_connect
  @ftp = Net::FTP.new(ENV['FTP_HOST'])
  @ftp.passive = true
  @ftp.(ENV['FTP_USERNAME'], ENV['FTP_PASSWORD'])
end

#ftp_downloadObject



101
102
103
104
105
106
107
# File 'lib/heroku-mongo-backup.rb', line 101

def ftp_download
  open(@file_name, 'w') do |file|
    file_content = @ftp.getbinaryfile(@file_name)
    file.binmode
    file.write file_content
  end
end

#ftp_uploadObject



97
98
99
# File 'lib/heroku-mongo-backup.rb', line 97

def ftp_upload
  @ftp.putbinaryfile(@file_name)
end

#loadObject



57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
# File 'lib/heroku-mongo-backup.rb', line 57

def load
  file = Zlib::GzipReader.open(@file_name)
  obj = Marshal.load file.read
  file.close

  obj.each do |col_name, records|
    next if col_name =~ /^system\./

    @db.drop_collection(col_name)
    dest_col = @db.create_collection(col_name)

    records.each do |record|
      dest_col.insert record
    end
  end
  
  # Load indexes here
  col_name = "system.indexes"
  dest_index_col = @db.collection(col_name)
  obj[col_name].each do |index|
    if index['_id']
      index['ns'] = index['ns'].sub(obj['system.indexes.db.name'], dest_index_col.db.name)
      dest_index_col.insert index
    end
  end
end

#restore(file_name, download_file = true) ⇒ Object



222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
# File 'lib/heroku-mongo-backup.rb', line 222

def restore file_name, download_file = true
  @file_name = file_name
  
  self.chdir
  
  if download_file
    if ENV['UPLOAD_TYPE'] == 'ftp'
      self.ftp_download
      @ftp.close
    else
      self.s3_download
    end
  end

  self.load
end

#s3_connectObject



109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
# File 'lib/heroku-mongo-backup.rb', line 109

def s3_connect
  bucket            = ENV['S3_BACKUPS_BUCKET']
  if bucket.nil?
    bucket          = ENV['S3_BACKUP_BUCKET']
  end
  if bucket.nil?
    bucket          = ENV['S3_BACKUP']
  end
  if bucket.nil?
    bucket          = ENV['S3_BUCKET']
  end

  access_key_id     = ENV['S3_KEY_ID']
  if access_key_id.nil?
    access_key_id   = ENV['S3_KEY']
  end
  if access_key_id.nil?
    access_key_id   = ENV['AWS_ACCESS_KEY_ID']
  end

  secret_access_key = ENV['S3_SECRET_KEY']
  if secret_access_key.nil?
    secret_access_key = ENV['S3_SECRET']
  end
  if secret_access_key.nil?
    secret_access_key = ENV['AWS_SECRET_ACCESS_KEY']
  end

  @bucket = HerokuMongoBackup::s3_connect(bucket, access_key_id, secret_access_key)
end

#s3_downloadObject



144
145
146
147
148
149
150
# File 'lib/heroku-mongo-backup.rb', line 144

def s3_download
  open(@file_name, 'w') do |file|
    file_content = HerokuMongoBackup::s3_download(@bucket, @file_name)
    file.binmode
    file.write file_content
  end
end

#s3_uploadObject



140
141
142
# File 'lib/heroku-mongo-backup.rb', line 140

def s3_upload
  HerokuMongoBackup::s3_upload(@bucket, @file_name)
end

#storeObject



33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
# File 'lib/heroku-mongo-backup.rb', line 33

def store
  backup = {}
  
  @db.collections.each do |col|
    backup['system.indexes.db.name'] = col.db.name if col.name == "system.indexes"

    records = []

    col.find().each do |record|
      records << record
    end

    backup[col.name] = records
  end
  
  marshal_dump = Marshal.dump(backup)
  
  file = File.new(@file_name, 'w')
  file.binmode
  file = Zlib::GzipWriter.new(file)
  file.write marshal_dump
  file.close
end