ey_cloud_server 1.4.26 → 1.4.28.pre

Sign up to get free protection for your applications and to get access to all the features.
data/bin/binary_log_purge CHANGED
@@ -20,10 +20,12 @@
20
20
  # Changelog 0.4 -> 1.0
21
21
  # - Add automatic create user for master to connect to replica
22
22
 
23
- require 'rubygems'
23
+ # Changelog 1.0 -> 1.1
24
+ # - Remove unecessary require of mysql
25
+ # - Remove -N from mysql command line (drops header row) for compatibility with 5.1 and 5.5
24
26
 
27
+ require 'rubygems'
25
28
  require 'net/smtp'
26
- require 'mysql'
27
29
  require 'yaml'
28
30
  require 'open3'
29
31
  require 'getoptlong'
@@ -103,7 +105,7 @@ def run_query(host, user, password, query)
103
105
  if query == 'show processlist'
104
106
  stdin, stdout, stderr = Open3.popen3("mysql -u#{user} -p#{password} #{options} -h#{host} -N -e\"#{query}\"|grep 'Binlog'")
105
107
  else
106
- stdin, stdout, stderr = Open3.popen3("mysql -u#{user} -p#{password} #{options} -h#{host} -N -e\"#{query}\"")
108
+ stdin, stdout, stderr = Open3.popen3("mysql -u#{user} -p#{password} #{options} -h#{host} -e\"#{query}\"")
107
109
  end
108
110
  query_error = stderr.read
109
111
  if query_error.length > 0
data/lib/ey_backup/cli.rb CHANGED
@@ -46,6 +46,10 @@ module EY
46
46
  options[:config] = config
47
47
  end
48
48
 
49
+ opts.on("-b", "--bucket BUCKET", "Override default S3 bucket name. (Be Careful!)") do |bucket|
50
+ options[:backup_bucket] = bucket
51
+ end
52
+
49
53
  opts.on("-t", "--tmp_dir TMPDIR", "Use the given directory for temporary storage.") do |tmp_dir|
50
54
  options[:tmp_dir] = tmp_dir
51
55
  end
@@ -57,7 +61,7 @@ module EY
57
61
  options[:db] = db
58
62
  end
59
63
 
60
- opts.on("-e", "--engine DATABASE_ENGINE", "The database engine. ex: mysql, postgres.") do |engine|
64
+ opts.on("-e", "--engine DATABASE_ENGINE", "The database engine. ex: mysql, postgres, mongodb.") do |engine|
61
65
  options[:engine] = engine
62
66
  end
63
67
 
@@ -0,0 +1,64 @@
1
+ module EY
2
+ module Backup
3
+ class Mongodb < Engine
4
+ register 'mongodb'
5
+
6
+ def dump(database_name, basename)
7
+ # Mongo dumps in directories. Compressing
8
+ file = basename
9
+
10
+ command = "mongodump --host #{host} -o #{file} --db #{database_name}; tar -cz #{file}"
11
+
12
+ if gpg?
13
+ command << " | " << GPGEncryptor.command_for(key_id)
14
+ file << GPGEncryptor.extension
15
+ end
16
+
17
+ command << " > #{file}"
18
+
19
+ run(command)
20
+
21
+ file
22
+ end
23
+
24
+ def load(database_name, file)
25
+ if database_exists?(database_name)
26
+ cycle_database(database_name)
27
+ else
28
+ create_database(database_name)
29
+ end
30
+
31
+ command = "cat #{file}"
32
+
33
+ if gpg?
34
+ raise "Cannot load a GPG backup"
35
+ end
36
+
37
+ command << " | mongorestore --host #{host} --db #{database_name}"
38
+
39
+ run(command)
40
+ end
41
+
42
+ def database_exists?(database_name)
43
+ runs?("mongo --host #{host} --quiet --eval \"for each(var db in db.runCommand('listDatabases').databases) if(db.sizeOnDisk > 1) print(db.name);\" admin | grep '#{database_name}'")
44
+ end
45
+
46
+ def drop_database(database_name)
47
+ runs?("mongo --host #{host} #{database_name} --quiet --eval 'printjson(db.dropDatabase());'")
48
+ end
49
+
50
+ def create_database(database_name)
51
+ runs?("mongo --host #{host} #{database_name} --quiet --eval 'db.createCollection('ey_backup');'")
52
+ end
53
+
54
+ def cycle_database(database_name)
55
+ drop_database(database_name)
56
+ create_database(database_name)
57
+ end
58
+
59
+ def suffix
60
+ /\.(gz)$/
61
+ end
62
+ end
63
+ end
64
+ end
@@ -4,9 +4,9 @@ module EY
4
4
  register 'postgresql'
5
5
 
6
6
  def dump(database_name, basename)
7
- file = basename + '.pgz'
7
+ file = basename + '.dump'
8
8
 
9
- command = "PGPASSWORD='#{password}' pg_dump -h #{host} --format=c --no-owner --no-privileges -U#{username} #{database_name}"
9
+ command = "PGPASSWORD='#{password}' pg_dump -h #{host} --format=c --no-owner --no-privileges -Upostgres #{database_name}"
10
10
 
11
11
  if gpg?
12
12
  command << " | " << GPGEncryptor.command_for(key_id)
@@ -33,7 +33,7 @@ module EY
33
33
  raise "Cannot load a GPG backup"
34
34
  end
35
35
 
36
- command << " | PGPASSWORD='#{password}' pg_restore -h #{host} --format=c --ignore-version -U#{username} -d #{database_name}"
36
+ command << " | PGPASSWORD='#{password}' pg_restore -h #{host} --format=c --ignore-version -Upostgres -d #{database_name}"
37
37
 
38
38
  run(command)
39
39
  end
@@ -56,7 +56,7 @@ module EY
56
56
  end
57
57
 
58
58
  def suffix
59
- /pgz(\.gpz)?$/
59
+ /\.(dump|gpz)$/
60
60
  end
61
61
  end
62
62
  end
data/lib/ey_backup.rb CHANGED
@@ -126,6 +126,7 @@ require lib_dir + '/backend'
126
126
 
127
127
  require lib_dir + '/engines/mysql_engine'
128
128
  require lib_dir + '/engines/postgresql_engine'
129
+ require lib_dir + '/engines/mongodb_engine'
129
130
 
130
131
  require lib_dir + '/processors/gzipper'
131
132
  require lib_dir + '/processors/splitter'
@@ -1,3 +1,3 @@
1
1
  module EY::CloudServer
2
- VERSION = '1.4.26'
2
+ VERSION = '1.4.28.pre'
3
3
  end
@@ -7,5 +7,8 @@ mysql_host: localhost
7
7
  postgresql_user: root
8
8
  postgresql_password:
9
9
  postgresql_host: localhost
10
+ mongodb_user: root
11
+ mongodb_passwd:
12
+ mongodb_host: localhost
10
13
  aws_secret_id: 'abcd123.id'
11
14
  aws_secret_key: 'abcd123.key'
@@ -0,0 +1,106 @@
1
+ require File.dirname(__FILE__) + '/spec_helper'
2
+
3
+ describe "MongoDB Backups" do
4
+ before(:each) do
5
+ @db_name = create_mongodb_database('test')
6
+ end
7
+
8
+ it "makes a backup" do
9
+ EY::Backup.run(["-c", backup_config_file, "-e", "mongodb"])
10
+
11
+ reset_logger
12
+
13
+ EY::Backup.run(["-c", backup_config_file, "-l", @db_name, "-e", "mongodb"])
14
+
15
+ stdout.should match(/0:#{@db_name}/)
16
+ end
17
+
18
+ it "makes a split backup" do
19
+ EY::Backup.run(["-c", backup_config_file, "-e", "mongodb", "-s", "100"])
20
+
21
+ backup = EY::Backup.run(["-c", backup_config_file, "-e", "mongodb", "-l", @db_name]).first
22
+ backup.parts.should > 1
23
+ end
24
+
25
+ it "makes GPG encrypted backups" do
26
+ import_gpg
27
+
28
+ EY::Backup.run(["-c", backup_config_file, '-e', 'mongodb', '-k', Helpers::PUBLIC_KEY_ID])
29
+
30
+ EY::Backup.run(["-c", backup_config_file, '-e', 'mongodb', "-l", @db_name])
31
+
32
+ stdout.should match(/0:#{@db_name}/)
33
+ end
34
+
35
+ it "restores a backup" do
36
+ run_mongocmd("db.foo.save({name: 'John Foo', age: 30});", @db_name).should be_true
37
+ run_mongocmd("db.bar.save({name: 'John Bar', age: 20});", @db_name).should be_true
38
+
39
+ EY::Backup.run(["-c", backup_config_file, '-e', 'mongodb'])
40
+
41
+ run_mongocmd("db.bar.drop();", @db_name).should be_true
42
+ run_mongocmd("db.bar.find();", @db_name).should be_false
43
+
44
+ reset_logger
45
+
46
+ EY::Backup.run(["-c", backup_config_file, "-l", @db_name, '-e', 'mongodb'])
47
+
48
+ stdout.should include("1 backup(s) found")
49
+
50
+ EY::Backup.run(["-c", backup_config_file, "-r", "0:#{@db_name}", '-e', 'mongodb'])
51
+
52
+ run_mongocmd("db.foo.find();", @db_name).should be_true
53
+ run_mongocmd("db.bar.find();", @db_name).should be_true
54
+ end
55
+
56
+ it "restores split backups" do
57
+ run_mongocmd("db.foo.save({name: 'John Foo', age: 30});", @db_name).should be_true
58
+ run_mongocmd("db.bar.save({name: 'John Bar', age: 20});", @db_name).should be_true
59
+
60
+ EY::Backup.run(["-c", backup_config_file, "-e", "MongoDB", "-s", "100"])
61
+ EY::Backup.run(["-c", backup_config_file, "-e", "MongoDB", "-l", @db_name]).first.parts.should > 1
62
+
63
+ run_mongocmd("db.bar.drop();", @db_name).should be_true
64
+ run_mongocmd("db.bar.find();", @db_name).should be_false
65
+
66
+ EY::Backup.run(["-c", backup_config_file, "-l", @db_name, '-e', 'mongodb'])
67
+
68
+ stdout.should include("1 backup(s) found")
69
+
70
+ EY::Backup.run(["-c", backup_config_file, "-r", "0:#{@db_name}", '-e', 'mongodb'])
71
+
72
+ run_mongocmd("db.foo.find();", @db_name).should be_true
73
+ run_mongocmd("db.bar.find();", @db_name).should be_true
74
+ end
75
+
76
+ it "downloads a split backup to 1 file" do
77
+ run_mongocmd("db.foo.save({name: 'John Foo', age: 30});", @db_name).should be_true
78
+ run_mongocmd("db.bar.save({name: 'John Bar', age: 20});", @db_name).should be_true
79
+
80
+ EY::Backup.run(["-c", backup_config_file, "-e", "mongodb", "-s", "100"])
81
+ EY::Backup.run(["-c", backup_config_file, "-e", "mongodb", "-l", @db_name]).first.parts.should > 1
82
+ EY::Backup.run(["-c", backup_config_file, "-e", 'mongodb', "--download", "0:#{@db_name}"])
83
+ files = Dir["#{EY::Backup.tmp_dir}/*#{@db_name}*"]
84
+
85
+ files.size.should == 1
86
+ FileUtils.rm(files.first)
87
+ end
88
+
89
+ end
90
+
91
+ describe "MongoDB Backups" do
92
+ before(:each) do
93
+ @dbs = [create_mongodb_database('first'), create_mongodb_database('second')]
94
+ end
95
+
96
+ it "makes multiple backup" do
97
+ EY::Backup.run(["-c", backup_config_file, "-e", "mongodb"])
98
+
99
+ reset_logger
100
+
101
+ @dbs.each do |db_name|
102
+ EY::Backup.run(["-c", backup_config_file, "-l", db_name, '-e', 'mongodb'])
103
+ stdout.should match(/0:#{db_name}/)
104
+ end
105
+ end
106
+ end
@@ -12,7 +12,7 @@ describe "Postgres Backups" do
12
12
 
13
13
  EY::Backup.run(["-c", backup_config_file, "-l", @db_name, "-e", "postgresql"])
14
14
 
15
- stdout.should match(/0:#{@db_name}.*\.pgz$/)
15
+ stdout.should match(/0:#{@db_name}.*\.dump.gz$/)
16
16
  end
17
17
 
18
18
  it "makes a split backup" do
data/spec/helpers.rb CHANGED
@@ -112,7 +112,7 @@ module Helpers
112
112
  end
113
113
 
114
114
  def create_postgresql_database(db_key, region = 'us-east-1')
115
- db_name = generate_database_name('postgresql')
115
+ db_name = generate_database_name('mongo')
116
116
  created_postgresql_dbs[db_key] = db_name
117
117
  drop_postgresql_database(db_key)
118
118
  # ssh -F /dev/null -o CheckHostIP=no -o StrictHostKeyChecking=no -i /home/$USER/.ssh/internal root@$DB_HOST "createdb -U postgres -h localhost -O $USER testdbreallytestingweee8"
@@ -122,6 +122,28 @@ module Helpers
122
122
  write_database_config('postgresql', postgresql_user, postgresql_password, postgresql_host, created_postgresql_dbs.values, region)
123
123
  db_name
124
124
  end
125
+
126
+ def drop_mongodb_database(db_key)
127
+ db_name = created_mongodb_dbs[db_key]
128
+ command=%Q{ssh -F /dev/null -o CheckHostIP=no -o StrictHostKeyChecking=no -i /home/#{mongodb_user}/.ssh/internal root@#{mongodb_host} "mongo --host localhost #{db_name} --quiet --eval 'printjson(db.dropDatabase());'"}
129
+ system(command)
130
+ end
131
+
132
+ def check_mongodb_database(db_name)
133
+ command=%Q{ssh -F /dev/null -o CheckHostIP=no -o StrictHostKeyChecking=no -i /home/#{mongodb_user}/.ssh/internal root@#{mongodb_host} "mongo --host localhost --quiet --eval "for each(var db in db.runCommand('listDatabases').databases) if(db.sizeOnDisk > 1) print(db.name);" admin | grep '#{db_name}'"}
134
+ system(command) || raise("Could not find db: #{db_name} with command:\n #{command}")
135
+ db_name
136
+ end
137
+
138
+ def create_mongodb_database(db_key, region = 'us-east-1')
139
+ db_name = generate_database_name('test')
140
+ drop_mongodb_database(db_key)
141
+ command=%Q{ssh -F /dev/null -o CheckHostIP=no -o StrictHostKeyChecking=no -i /home/#{mongodb_user}/.ssh/internal root@#{mongodb_host} "mongo --host localhost #{db_name} --quiet --eval 'db.foo.save({ name : "derp"});'"}
142
+ system(command) || raise("Could not create db: #{db_name} with command:\n #{command}")
143
+ write_database_config('mongodb', mongodb_user, mongodb_password, mongodb_host, created_mongodb_dbs.values, region)
144
+ db_name
145
+ end
146
+
125
147
 
126
148
  def write_database_config(type, root_user, root_password, host, databases, region)
127
149
  @database_config = {
@@ -167,6 +189,10 @@ module Helpers
167
189
  system("PGPASSWORD='#{postgresql_password}' psql -c '#{command}' -h #{postgresql_host} -U #{postgresql_user} #{database}")
168
190
  end
169
191
 
192
+ def run_mongocmd(command, database)
193
+ system("mongo #{database} --quiet --eval \"#{command}\" --quiet")
194
+ end
195
+
170
196
  def tmp_dir
171
197
  if spec_config['tmp_dir'].blank?
172
198
  File.dirname(__FILE__) + "/tmp/"
@@ -183,6 +209,10 @@ module Helpers
183
209
  spec_config['postgresql_user'] || raise("No postgresql user provided")
184
210
  end
185
211
 
212
+ def mongodb_user
213
+ spec_config['mongodb_user'] || raise("No mongodb user provided")
214
+ end
215
+
186
216
  def mysql_password
187
217
  spec_config['mysql_password']
188
218
  end
@@ -191,6 +221,10 @@ module Helpers
191
221
  spec_config['postgresql_password']
192
222
  end
193
223
 
224
+ def mongodb_password #<- is this really needed? Supported mongo will run in trusted mode
225
+ spec_config['mongodb_password']
226
+ end
227
+
194
228
  def mysql_host
195
229
  spec_config['mysql_host']
196
230
  end
@@ -199,6 +233,10 @@ module Helpers
199
233
  spec_config['postgresql_host']
200
234
  end
201
235
 
236
+ def mongodb_host
237
+ spec_config['mongodb_host']
238
+ end
239
+
202
240
  def created_mysql_dbs
203
241
  @created_mysql_dbs ||= {}
204
242
  end
@@ -207,6 +245,10 @@ module Helpers
207
245
  @created_postgresql_dbs ||= {}
208
246
  end
209
247
 
248
+ def created_mongodb_dbs
249
+ @created_mongodb_dbs ||= {}
250
+ end
251
+
210
252
  def spec_config
211
253
  Helpers.spec_config
212
254
  end
metadata CHANGED
@@ -1,13 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ey_cloud_server
3
3
  version: !ruby/object:Gem::Version
4
- hash: 51
5
- prerelease:
4
+ hash: 961915908
5
+ prerelease: 7
6
6
  segments:
7
7
  - 1
8
8
  - 4
9
- - 26
10
- version: 1.4.26
9
+ - 28
10
+ - pre
11
+ version: 1.4.28.pre
11
12
  platform: ruby
12
13
  authors:
13
14
  - Engine Yard
@@ -15,7 +16,7 @@ autorequire:
15
16
  bindir: bin
16
17
  cert_chain: []
17
18
 
18
- date: 2011-11-29 00:00:00 Z
19
+ date: 2011-12-22 00:00:00 Z
19
20
  dependencies:
20
21
  - !ruby/object:Gem::Dependency
21
22
  name: json
@@ -331,6 +332,7 @@ files:
331
332
  - lib/ey_backup/database.rb
332
333
  - lib/ey_backup/dumper.rb
333
334
  - lib/ey_backup/engine.rb
335
+ - lib/ey_backup/engines/mongodb_engine.rb
334
336
  - lib/ey_backup/engines/mysql_engine.rb
335
337
  - lib/ey_backup/engines/postgresql_engine.rb
336
338
  - lib/ey_backup/loader.rb
@@ -350,6 +352,7 @@ files:
350
352
  - spec/ey_backup/backend_spec.rb
351
353
  - spec/ey_backup/backup_spec.rb
352
354
  - spec/ey_backup/cli_spec.rb
355
+ - spec/ey_backup/mongo_backups_spec.rb
353
356
  - spec/ey_backup/mysql_backups_spec.rb
354
357
  - spec/ey_backup/postgres_backups_spec.rb
355
358
  - spec/ey_backup/spec_helper.rb
@@ -385,12 +388,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
385
388
  required_rubygems_version: !ruby/object:Gem::Requirement
386
389
  none: false
387
390
  requirements:
388
- - - ">="
391
+ - - ">"
389
392
  - !ruby/object:Gem::Version
390
- hash: 3
393
+ hash: 25
391
394
  segments:
392
- - 0
393
- version: "0"
395
+ - 1
396
+ - 3
397
+ - 1
398
+ version: 1.3.1
394
399
  requirements: []
395
400
 
396
401
  rubyforge_project:
@@ -406,6 +411,7 @@ test_files:
406
411
  - spec/ey_backup/backend_spec.rb
407
412
  - spec/ey_backup/backup_spec.rb
408
413
  - spec/ey_backup/cli_spec.rb
414
+ - spec/ey_backup/mongo_backups_spec.rb
409
415
  - spec/ey_backup/mysql_backups_spec.rb
410
416
  - spec/ey_backup/postgres_backups_spec.rb
411
417
  - spec/ey_backup/spec_helper.rb