ey_cloud_server 1.4.26 → 1.4.28.pre

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/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