ey_cloud_server 1.4.54 → 1.5.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.
@@ -6,7 +6,7 @@ module EY
6
6
  def dump(database_name, basename)
7
7
  file = basename + '.sql'
8
8
 
9
- command = "mysqldump #{username_option} #{host_option} #{single_transaction_option(database_name)} #{routines_option} #{master_data_option} #{databases_option(database_name)} 2> /tmp/eybackup.$$.dumperr"
9
+ command = "( #{server_id} mysqldump #{username_option} #{host_option} #{single_transaction_option(database_name)} #{routines_option} #{master_data_option} #{databases_option(database_name)} ) "
10
10
 
11
11
  if gpg?
12
12
  command << " | " << GPGEncryptor.command_for(key_id)
@@ -17,6 +17,8 @@ module EY
17
17
  end
18
18
 
19
19
  command << " > #{file}"
20
+
21
+ block_concurrent(database_name) unless allow_concurrent
20
22
 
21
23
  run(command, database_name)
22
24
 
@@ -27,14 +29,16 @@ module EY
27
29
  command = "cat #{file}"
28
30
 
29
31
  if file =~ /.gpz$/ # GPG?
30
- abort "Cannot restore a GPG backup directly; decrypt the file (#{file}) using your key and then load using the mysql client."
32
+ abort "\nCannot restore a GPG backup directly; decrypt the file (#{file}) using your key and then load using the mysql client.
33
+ To decrypt a backup: https://support.cloud.engineyard.com/hc/en-us/articles/205413948-Use-PGP-Encrypted-Database-Backups-with-Engine-Yard-Cloud#restore
34
+ Once decrypted, restore with: `gunzip -f < <filename> | mysql #{username_option} #{host_option} #{database_name}`\n\n"
31
35
  else
32
36
  command << " | " << GZipper.gunzip
33
37
  end
34
38
 
35
39
  cycle_database(database_name)
36
40
 
37
- command << " | mysql #{username_option} #{host_option} #{database_name} 2> /tmp/eybackup.$$.dumperr"
41
+ command << " | mysql #{username_option} #{host_option} #{database_name} "
38
42
 
39
43
  run(command, database_name)
40
44
  end
@@ -52,12 +56,19 @@ module EY
52
56
  "--routines"
53
57
  end
54
58
 
59
+ def server_id
60
+ if log_bin_on? and log_coordinates
61
+ stdout = %x{mysql #{username_option} #{host_option} -BN -e"select @@global.server_id"}
62
+ "echo '-- Server_id: #{stdout.strip}' && "
63
+ end
64
+ end
65
+
55
66
  def master_data_option
56
- "--master-data=2" if log_bin_on?
67
+ "--master-data=2" if log_bin_on? and log_coordinates
57
68
  end
58
69
 
59
70
  def databases_option(db)
60
- "--add-drop-database --databases #{db}"
71
+ "#{db}"
61
72
  end
62
73
 
63
74
  def host_option
@@ -6,7 +6,7 @@ module EY
6
6
  def dump(database_name, basename)
7
7
  file = basename + '.dump'
8
8
 
9
- command = "PGPASSWORD='#{password}' pg_dump -h #{host} --create --format=c -Upostgres #{database_name} 2> /tmp/eybackup.$$.dumperr"
9
+ command = "PGPASSWORD='#{password}' pg_dump -h #{host} --create --format=c -U#{username} #{database_name} "
10
10
 
11
11
  if gpg?
12
12
  command << " | " << GPGEncryptor.command_for(key_id)
@@ -15,6 +15,7 @@ module EY
15
15
 
16
16
  command << " > #{file}"
17
17
 
18
+ block_concurrent(database_name) unless allow_concurrent
18
19
  run(command, database_name)
19
20
 
20
21
  file
@@ -22,25 +23,39 @@ module EY
22
23
 
23
24
  def load(database_name, file)
24
25
  if file =~ /.gpz$/ # GPG?
25
- abort "Cannot restore a GPG backup directly; decrypt the file (#{file}) using your key and then load with pg_restore."
26
+ abort "\nCannot restore a GPG backup directly; decrypt the file (#{file}) using your key and then load with pg_restore.
27
+ To decrypt a backup: https://support.cloud.engineyard.com/hc/en-us/articles/205413948-Use-PGP-Encrypted-Database-Backups-with-Engine-Yard-Cloud#restore
28
+ Once decrypted, restore with: `pg_restore -h #{host} --format=c --clean -U#{username} -d #{database_name} <filename>`\n\n"
26
29
  end
27
30
 
28
31
  cycle_database(database_name)
32
+
33
+ # Exclude Extension Comments
34
+ toc_file = "#{file}.toc"
35
+ table_of_contents(file, toc_file)
29
36
 
30
37
  command = "cat #{file}"
31
38
 
32
- command << " | PGPASSWORD='#{password}' pg_restore -h #{host} --format=c -Upostgres -d #{database_name} 2> /tmp/eybackup.$$.dumperr"
39
+ command << " | PGPASSWORD='#{password}' pg_restore -L #{toc_file} -h #{host} --format=c -U#{username} -d #{database_name}"
33
40
 
34
41
  run(command, database_name)
42
+
43
+ system("rm #{toc_file}") if File.exists?(toc_file)
44
+
45
+ # Analyze database unless disabled
46
+ unless skip_analyze
47
+ verbose "Analyzing database '#{database_name}', use --skip-analyze to skip this step."
48
+ %x{PGPASSWORD='#{password}' vacuumdb -h #{host} -U#{username} -d #{database_name} --analyze-only}
49
+ end
35
50
  end
36
51
 
37
52
  def check_connections(database_name)
38
- active_connections = %x{PGPASSWORD='#{password}' psql -U postgres -h #{host} -t -c "select count(*) from pg_stat_activity where datname='#{database_name}';"}
53
+ active_connections = %x{PGPASSWORD='#{password}' psql -U#{username} -h #{host} -t postgres -c "select count(*) from pg_stat_activity where datname='#{database_name}';"}
39
54
 
40
55
  if active_connections.to_i > 0
41
56
  res = ''
42
57
  unless force
43
- puts "There are currently #{stdout.string.to_i} connections on database: '#{database_name}'; can I kill these to continue (Y/n):"
58
+ puts "There are currently #{active_connections} connections on database: '#{database_name}'; can I kill these to continue (Y/n):"
44
59
  Timeout::timeout(30){
45
60
  res = gets.strip
46
61
  }
@@ -55,13 +70,13 @@ module EY
55
70
  end
56
71
 
57
72
  def cancel_connections(database_name)
58
- %x{psql -U postgres -h #{host} -c"SELECT pg_terminate_backend(pg_stat_activity.pid)
73
+ %x{psql -U#{username} -h #{host} postgres -c"SELECT pg_terminate_backend(pg_stat_activity.pid)
59
74
  FROM pg_stat_activity
60
75
  WHERE pg_stat_activity.datname = '#{database_name}';"}
61
76
  end
62
77
 
63
78
  def drop_database(database_name)
64
- command = "PGPASSWORD='#{password}' dropdb -h #{host} -Upostgres #{database_name}"
79
+ command = "PGPASSWORD='#{password}' dropdb -h #{host} -U#{username} #{database_name}"
65
80
  verbose "Dropping Database with: #{command}"
66
81
  %x{#{command}}
67
82
  end
@@ -73,14 +88,23 @@ module EY
73
88
  end
74
89
 
75
90
  def check_if_replica
76
- stdout = %x{PGPASSWORD='#{password}' psql -U postgres -h #{host} -t -c "select pg_is_in_recovery()"| head -n 1}
91
+ command = "PGPASSWORD='#{password}' psql -U#{username} -h #{host} -t -c 'select pg_is_in_recovery()' postgres| head -n 1"
92
+ verbose "Checking for replica state with: #{command}"
93
+ stdout = %x{#{command}}
77
94
  unless stdout.chomp =~ /^\W*f$/
78
95
  EY::Backup.logger.fatal(%Q{ERROR: Target host: '#{host}' is currently a replica in recovery mode; restore operations need to be processed against the master.})
79
96
  end
80
97
  end
81
98
 
99
+ def table_of_contents(file, toc_file)
100
+ command = %Q{pg_restore -l #{file} | sed -e 's/^\\\(.* COMMENT - EXTENSION .*\\\)/;\\1/g' \
101
+ -e 's/^\\\(.* rdsadmin$\\\)/;\\1/g' > #{toc_file}}
102
+ verbose "Creating table of contents: #{command}"
103
+ %x{#{command}}
104
+ end
105
+
82
106
  def create_command(database_name)
83
- %x{PGPASSWORD='#{password}' psql -U postgres -h #{host} -t -c "SELECT 'CREATE DATABASE ' || datname ||
107
+ command="PGPASSWORD='#{password}' psql -U#{username} -h #{host} -t postgres -c \"SELECT 'CREATE DATABASE ' || datname ||
84
108
  ' WITH OWNER ' || pg_user.usename ||
85
109
  CASE (select pg_encoding_to_char(encoding) from pg_database where datname='template1')
86
110
  WHEN pg_encoding_to_char(encoding)
@@ -94,8 +118,9 @@ module EY
94
118
  FROM pg_database
95
119
  INNER JOIN pg_user
96
120
  ON pg_user.usesysid = pg_database.datdba
97
- WHERE datname = '#{database_name}'"
98
- }
121
+ WHERE datname = '#{database_name}'\""
122
+ verbose "Getting create info: #{command}"
123
+ %x{#{command}}
99
124
  end
100
125
 
101
126
  def cycle_database(database_name)
@@ -105,7 +130,7 @@ module EY
105
130
  else
106
131
  check_connections(database_name)
107
132
  drop_database(database_name)
108
- %x{PGPASSWORD='#{password}' psql -U postgres -h #{host} -t -c "#{create_cmd}"}
133
+ %x{PGPASSWORD='#{password}' psql -U#{username} -h #{host} -t postgres -c "#{create_cmd}"}
109
134
  end
110
135
  end
111
136
 
@@ -16,8 +16,10 @@ module EY
16
16
  end
17
17
 
18
18
  def run
19
- info "Restoring #{@database.name}"
19
+
20
20
  backup = download
21
+ mode = backup.basename =~ /.gpz$/ ? "Downloading" : "Restoring"
22
+ info "#{mode} #{@database.name}"
21
23
  backup.load!
22
24
  backup.remove_joined_file!
23
25
  end
@@ -1,8 +1,15 @@
1
+ class String
2
+ def truncate(limit = 1)
3
+ self.match(%r{^(.{0,#{limit}})})[1]
4
+ end
5
+ end
6
+
1
7
  module EY
2
8
  module Backup
3
9
  class Logger
4
10
  extend Forwardable
5
11
  require 'shellwords'
12
+ require 'fileutils'
6
13
 
7
14
  attr_accessor :stdout, :stderr
8
15
 
@@ -22,21 +29,22 @@ module EY
22
29
 
23
30
  def push_dashboard_alert(message, alert_level, db = nil)
24
31
  message.gsub!("\n", '\n')
32
+ message = Shellwords.escape(message).truncate(255)
25
33
  type="process-dbbackup"
26
34
  type = type + " #{db}" unless db.nil?
27
35
  full_txt= "Severity: #{alert_level}\n" \
28
36
  + "Time: #{Time.now.to_i}\n" \
29
37
  + "Type: #{type}\n" \
30
- + "Plugin: exec\n" \
31
- + "raw_message: '#{message}'"
38
+ + "Plugin: exec\n"
32
39
  full_txt = Shellwords.escape(full_txt)
40
+ full_txt += "raw_message:\\ \\'#{message}\\'"
33
41
  alert_command = %Q(echo #{full_txt} | /engineyard/bin/ey-alert.rb 2>&1)
34
42
  verbose "Sending dashboard alert"
35
43
  system(alert_command)
36
44
  end
37
45
 
38
46
  def info(msg)
39
- puts "#{Time.now} #{msg}"
47
+ stdout.puts "#{Time.now} #{msg}"
40
48
  end
41
49
 
42
50
  def verbose(msg)
@@ -46,24 +54,48 @@ module EY
46
54
  def set_verbose()
47
55
  @verbose = true
48
56
  end
57
+
58
+ def set_log_path=(path)
59
+ @status_path = path
60
+ FileUtils.mkdir_p(@status_path)
61
+ end
49
62
 
50
63
  def say(msg, newline = true)
51
64
  newline ? info(msg) : stdout.print(msg)
52
65
  end
53
66
 
54
- def okay(msg, db = nil)
55
- stderr.puts("#{Time.now} OKAY: #{msg}")
56
- # push_dashboard_alert(msg, "OKAY", db), we don't push OKAY alerts, we push a summary alert instead.
67
+ def okay(db, size)
68
+ filepath = File.join(@status_path, "#{db}.sizes")
69
+ %x{LOG=$(tail -n 100 #{filepath}); echo "$LOG" > #{filepath}} if File.exists?(filepath)
70
+ %x{echo "#{Time.now()} #{size}" >> #{filepath}}
71
+ msg = "Backup successful for '#{db}' after previous failure."
72
+ push_dashboard_alert(msg, 'OKAY', db) if clear_alert?(db)
57
73
  end
58
74
 
59
75
  def warn(msg, db = nil)
60
- stderr.puts("#{Time.now} WARNING: #{msg}")
76
+ stdout.puts("#{Time.now} WARNING: #{msg}")
77
+ set_alert(msg, db) unless db.nil?
61
78
  push_dashboard_alert(msg, "WARNING", db)
62
79
  end
63
80
 
64
81
  def error(msg, db = nil)
65
- stderr.puts("#{Time.now} ERROR: #{msg}")
66
- push_dashboard_alert("#{msg}. Details at /var/log/eybackup.log.", "FAILURE", db)
82
+ stdout.puts("#{Time.now} ERROR: #{msg}")
83
+ set_alert(msg, db) unless db.nil?
84
+ push_dashboard_alert("#{msg} Details at /var/log/eybackup.log.", "FAILURE", db)
85
+ end
86
+
87
+ def set_alert(msg, db)
88
+ fullPath = File.join(@status_path, "#{db}.alert")
89
+ File.open(fullPath, 'a') { |file| file.puts "#{Time.now}: #{msg}"}
90
+ end
91
+
92
+ def clear_alert?(db)
93
+ begin
94
+ File.delete(File.join(@status_path, "#{db}.alert"))
95
+ true
96
+ rescue Errno::ENOENT
97
+ false
98
+ end
67
99
  end
68
100
 
69
101
  def exception(type, msg)
@@ -71,7 +103,7 @@ module EY
71
103
  end
72
104
 
73
105
  def debug(msg)
74
- stderr.puts("#{Time.now} DEBUG: #{msg}")
106
+ stdout.puts("#{Time.now} DEBUG: #{msg}")
75
107
  end
76
108
 
77
109
  end
@@ -5,7 +5,7 @@ module EY
5
5
  include Logging
6
6
 
7
7
  CHUNK_SIZE = 1024 * 64
8
- MAX_FILE_SIZE = (4.5*1024*1024*1024).to_i #4.5GB
8
+ MAX_FILE_SIZE = (4.9*1024*1024*1024*1024).to_i #4.9TB
9
9
 
10
10
  def self.dump(file, split_size)
11
11
  split_size ||= MAX_FILE_SIZE
@@ -42,14 +42,11 @@ module EY
42
42
  pid, stdin, stdout, stderr = Open4.popen4("bash -o pipefail -c #{escaped_command}")
43
43
  pid, status = Process::waitpid2(pid)
44
44
 
45
- verbose "stdout: #{stdout.read}"
46
- verbose "stderr: #{stderr.read}"
47
45
  verbose "status: #{status}"
48
46
 
49
47
  if ! status.success?
50
- dumperr = File.exists?("/tmp/eybackup.#{pid}.dumperr") ? File.read("/tmp/eybackup.#{pid}.dumperr") : status
51
- err_msg = "DB dump failed. The error returned was: #{dumperr}"
52
- verbose "#{db} backup failed: #{err_msg}"
48
+ dumperr = File.exists?("/tmp/eybackup.#{pid}.dumperr") ? File.read("/tmp/eybackup.#{pid}.dumperr") : "#{status}: #{stderr.read.chomp}: #{stdout.read.chomp}"
49
+ err_msg = "#{db} backup failed! The error returned was: #{dumperr}"
53
50
  error(err_msg, db)
54
51
  end
55
52
 
data/lib/ey_backup.rb CHANGED
@@ -44,6 +44,7 @@ module EY
44
44
  class << self
45
45
  attr_accessor :logger
46
46
  attr_accessor :tmp_dir
47
+ attr_accessor :log_dir
47
48
  end
48
49
 
49
50
  def self.run(argv = ARGV)
@@ -96,11 +97,12 @@ module EY
96
97
  if @options[:db].nil? || @options[:db].empty?
97
98
  @options[:databases]
98
99
  else
99
- [@options[:db]]
100
+ [@options[:db]].flatten
100
101
  end
101
102
  end
102
103
 
103
104
  def setup
105
+ setup_log_dir
104
106
  setup_logger
105
107
  setup_tmp_dir
106
108
  setup_backend
@@ -117,6 +119,7 @@ module EY
117
119
  EY::Backup.logger.set_verbose
118
120
  end
119
121
  end
122
+ EY::Backup.logger.set_log_path=EY::Backup.log_dir
120
123
  end
121
124
 
122
125
  def setup_tmp_dir
@@ -126,6 +129,14 @@ module EY
126
129
  EY::Backup.tmp_dir = "/mnt/tmp"
127
130
  end
128
131
  end
132
+
133
+ def setup_log_dir
134
+ if @options[:log_dir]
135
+ EY::Backup.log_dir = @options[:log_dir]
136
+ else
137
+ EY::Backup.log_dir = "/var/log/engineyard/eybackup"
138
+ end
139
+ end
129
140
 
130
141
  def setup_backend
131
142
  @backend = Backend.new(@options[:aws_secret_id], @options[:aws_secret_key], @options[:region], @options[:backup_bucket])
@@ -136,7 +147,7 @@ module EY
136
147
  if ! @options.key?(:dbhost) or @options[:dbhost] == nil or @options[:dbhost] == ""
137
148
  @options[:dbhost] = 'localhost'
138
149
  end
139
- @engine = engine_class.new(@options[:dbuser], @options[:dbpass], @options[:dbhost], @options[:key_id], @options[:force])
150
+ @engine = engine_class.new(@options[:dbuser], @options[:dbpass], @options[:dbhost], @options[:key_id], @options[:force], @options[:allow_concurrent], @options[:skip_analyze], @options[:log_coordinates])
140
151
  end
141
152
 
142
153
  def dispatch
@@ -1,5 +1,5 @@
1
1
  module EY
2
2
  module CloudServer
3
- VERSION = '1.4.54'
3
+ VERSION = '1.5.0'
4
4
  end
5
5
  end
@@ -0,0 +1,11 @@
1
+ ---
2
+ tmp_dir:
3
+ data_json:
4
+ mysql_user: jenkins
5
+ mysql_password: jenkins
6
+ mysql_host: localhost
7
+ postgresql_user: postgres
8
+ postgresql_password: postgres
9
+ postgresql_host: localhost
10
+ aws_secret_id: 'abcd123.id'
11
+ aws_secret_key: 'abcd123.key'
@@ -3,10 +3,12 @@ require File.dirname(__FILE__) + '/spec_helper'
3
3
  describe EY::Backup do
4
4
  before(:each) do
5
5
  @db_name = create_mysql_database('first')
6
+ setup_dna({:db_stack_name => "mysql5_5"})
6
7
  end
7
8
 
8
9
  after(:each) do
9
10
  drop_mysql_database(@db_name)
11
+ teardown_dna
10
12
  end
11
13
 
12
14
  describe "#list" do
@@ -3,10 +3,12 @@ require File.dirname(__FILE__) + '/spec_helper'
3
3
  describe "MySQL Backups" do
4
4
  before(:each) do
5
5
  @db_name = create_mysql_database('first')
6
+ setup_dna({:db_stack_name => "mysql5_5"})
6
7
  end
7
8
 
8
9
  after(:each) do
9
10
  drop_mysql_database(@db_name)
11
+ teardown_dna
10
12
  end
11
13
 
12
14
  describe "--quiet" do
@@ -3,11 +3,13 @@ require File.dirname(__FILE__) + '/spec_helper'
3
3
  describe "MySQL Backups" do
4
4
  before(:each) do
5
5
  @db_name = create_mysql_database('first')
6
+ setup_dna({:db_stack_name => "mysql5_5"})
6
7
  mk_tmp
7
8
  end
8
9
 
9
10
  after(:each) do
10
11
  drop_mysql_database(@db_name)
12
+ teardown_dna
11
13
  end
12
14
 
13
15
  it "makes a backup" do
@@ -125,17 +127,37 @@ describe "MySQL Backups" do
125
127
  run_sql("SELECT * FROM `bar`;", @db_name).should be_true
126
128
  FileUtils.rm(file)
127
129
  end
130
+
131
+ it 'detects a backup failure due to an invalid view definition and reports it to stdout' do
132
+
133
+ run_sql("CREATE TABLE `foo` (`id` int(11) NOT NULL auto_increment, PRIMARY KEY(`id`));", @db_name).should be_truthy
134
+ run_sql("CREATE TABLE `bar` (`id` int(11) NOT NULL auto_increment, PRIMARY KEY(`id`));", @db_name).should be_truthy
135
+ run_sql("CREATE view `vw_foobar` as select `foo`.`id` as `foo_id`, `bar`.`id` as `bar_id` from `foo` inner join `bar` on `foo`.`id` = `bar`.`id`;", @db_name).should be_truthy
136
+ run_sql("DROP TABLE `bar`;", @db_name).should be_truthy
137
+
138
+ reset_logger
139
+
140
+ EY::Backup.run(["-c", backup_config_file])
141
+ stdout.should match(/mysqldump: Couldn't execute 'SHOW FIELDS FROM `vw_foobar`'/)
142
+
143
+ files = Dir["#{EY::Backup.tmp_dir}/*#{@db_name}*"]
144
+
145
+ files.size.should == 1
146
+ FileUtils.rm(files.first)
147
+ end
128
148
  end
129
149
 
130
150
  describe "MySQL Backups" do
131
151
  before(:each) do
132
152
  @dbs = [create_mysql_database('first'), create_mysql_database('second')]
153
+ setup_dna({:db_stack_name => "mysql5_5"})
133
154
  end
134
155
 
135
156
  after(:each) do
136
157
  @dbs.each do |db|
137
158
  drop_mysql_database(db)
138
159
  end
160
+ teardown_dna
139
161
  end
140
162
 
141
163
  it "makes a backup" do
@@ -154,10 +176,12 @@ describe "a multi-region backup" do
154
176
  describe "in japan!" do
155
177
  before(:each) do
156
178
  @db_name = create_mysql_database('speaking_japanese', 'ap-northeast-1')
179
+ setup_dna({:db_stack_name => "mysql5_5"})
157
180
  end
158
181
 
159
182
  after(:each) do
160
183
  drop_mysql_database(@db_name)
184
+ teardown_dna
161
185
  end
162
186
 
163
187
  it "makes a split backup" do
@@ -193,10 +217,12 @@ describe "a multi-region backup" do
193
217
  describe "in europe!" do
194
218
  before(:each) do
195
219
  @db_name = create_mysql_database('speaking_esperanto', 'eu-west-1')
220
+ setup_dna({:db_stack_name => "mysql5_5"})
196
221
  end
197
222
 
198
223
  after(:each) do
199
224
  drop_mysql_database(@db_name)
225
+ teardown_dna
200
226
  end
201
227
 
202
228
  it "makes a split backup" do
@@ -3,10 +3,12 @@ require File.dirname(__FILE__) + '/spec_helper'
3
3
  describe "Postgres Backups" do
4
4
  before(:each) do
5
5
  @db_name = create_postgresql_database('first')
6
+ setup_dna({:db_stack_name => "postgres9_5"})
6
7
  end
7
8
 
8
9
  after(:each) do
9
10
  drop_postgresql_database(@db_name)
11
+ teardown_dna
10
12
  end
11
13
 
12
14
  it "makes a custom format backup" do
@@ -18,6 +20,16 @@ describe "Postgres Backups" do
18
20
 
19
21
  stdout.should match(/0:#{@db_name}.*\.dump$/)
20
22
  end
23
+
24
+ it "makes a custom backup and detects that the db is Postgres" do
25
+ EY::Backup.run(["-c", backup_config_file])
26
+
27
+ reset_logger
28
+
29
+ EY::Backup.run(["-c", backup_config_file, "-l", @db_name, "-e", "postgresql"])
30
+
31
+ stdout.should match(/0:#{@db_name}.*\.dump$/)
32
+ end
21
33
 
22
34
  it "makes a split backup" do
23
35
  EY::Backup.run(["-c", backup_config_file, "-e", "postgresql", "-s", "100"])
data/spec/helpers.rb CHANGED
@@ -19,18 +19,28 @@ module Helpers
19
19
  @mock_environment_name => {:id => 1}
20
20
  }))
21
21
 
22
- FileUtils.mkdir_p(tmp_dir)
23
- Dir.glob("#{tmp_dir}/*").each do |f|
22
+ create_or_clean_dir(tmp_dir)
23
+ create_or_clean_dir(log_dir)
24
+
25
+ # FileUtils.mkdir_p(tmp_dir)
26
+ # FileUtils.mkdir_p(log_dir)
27
+ # Dir.glob("#{tmp_dir}/*").each do |f|
28
+ # FileUtils.rm(f)
29
+ # end
30
+ stub_configs
31
+ end
32
+
33
+ def create_or_clean_dir(dir)
34
+ FileUtils.mkdir_p(dir)
35
+ Dir.glob("#{dir}/*").each do |f|
24
36
  FileUtils.rm(f)
25
37
  end
26
-
27
- stub_configs
28
38
  end
29
39
 
30
40
  def stub_configs
31
41
  #print "in stub_configs: #{YAML::dump(@database_config)}, #{YAML::dump(spec_config)}\n"
32
42
  config = @database_config || spec_config
33
- config = config.merge({ :tmp_dir => tmp_dir })
43
+ config = config.merge({ :tmp_dir => tmp_dir, :log_dir => log_dir })
34
44
  # print "in stub_configs2: #{YAML::dump(config)}\n"
35
45
  File.open(backup_config_file, "w") do |f|
36
46
  f.puts YAML.dump(config )
@@ -38,6 +48,9 @@ module Helpers
38
48
  end
39
49
 
40
50
  def import_gpg
51
+ # GPG v2.1+ dropped support for the --secret-keyring option (https://lists.gnupg.org/pipermail/gnupg-devel/2014-December/029296.html)
52
+ # This means that we need to import private keys too
53
+ system("gpg --import #{PRIVATE_KEY_PATH}") || raise("Could not import public key")
41
54
  system("gpg --import #{PUBLIC_KEY_PATH}") || raise("Could not import public key")
42
55
  end
43
56
 
@@ -55,7 +68,7 @@ module Helpers
55
68
  return File.read(PUBLIC_KEY_PATH), File.read(PRIVATE_KEY_PATH)
56
69
  end
57
70
 
58
- def run_after
71
+ def run_after(skip_file_remove = false)
59
72
  FileUtils.rm_f(backup_config_file)
60
73
  filenames = Dir.glob("#{tmp_dir}/*")
61
74
  if filenames.any?
@@ -63,16 +76,17 @@ module Helpers
63
76
  end
64
77
  end
65
78
 
66
- def teardown_dna(data)
67
- FileUtils.rm_f("#{tmp_dir}/dna.json")
79
+ def teardown_dna()
80
+ FileUtils.rm_f("#{tmp_dir}/chef/dna.json")
81
+ FileUtils.rm_r("#{tmp_dir}/chef")
68
82
  end
69
83
 
70
84
  def setup_dna(data)
71
- FileUtils.mkdir_p("#{tmp_dir}")
72
- if File.exist?("#{tmp_dir}/dna.json")
73
- FileUtils.rm("#{tmp_dir}/dna.json")
85
+ FileUtils.mkdir_p("#{tmp_dir}/chef")
86
+ if File.exist?("#{tmp_dir}/chef/dna.json")
87
+ FileUtils.rm("#{tmp_dir}/chef/dna.json")
74
88
  end
75
- File.open("#{tmp_dir}/dna.json", "w") do |f|
89
+ File.open("#{tmp_dir}/chef/dna.json", "w") do |f|
76
90
  f.puts data.to_json
77
91
  end
78
92
  end
@@ -80,7 +94,7 @@ module Helpers
80
94
  def backup_config_file
81
95
  "#{tmp_dir}/spec_backups.yml"
82
96
  end
83
-
97
+
84
98
  def mk_tmp
85
99
  FileUtils.mkdir_p("/tmp")
86
100
  end
@@ -102,7 +116,7 @@ module Helpers
102
116
  write_database_config('mysql', mysql_user, mysql_password, mysql_host, created_mysql_dbs.values, region)
103
117
  db_name
104
118
  end
105
-
119
+
106
120
  def drop_mysql_database(db_name)
107
121
  command = %Q{mysql -u#{mysql_user} -h#{mysql_host} #{mysql_password_option} -e "drop database if exists #{db_name};"}
108
122
  puts "*** MySQL Drop Command: #{command}"
@@ -184,6 +198,14 @@ module Helpers
184
198
  end
185
199
  end
186
200
 
201
+ def log_dir
202
+ if spec_config['log_dir'].nil?
203
+ File.dirname(__FILE__) + "/log/"
204
+ else
205
+ spec_config['log_dir'] || File.dirname("./log/")
206
+ end
207
+ end
208
+
187
209
  def mysql_user
188
210
  spec_config['mysql_user'] || "root"
189
211
  end
@@ -281,5 +303,9 @@ module Helpers
281
303
  EY::Backup.logger.stdout.string
282
304
  end
283
305
 
306
+ def stderr
307
+ EY::Backup.logger.stderr.string
308
+ end
309
+
284
310
  load_spec_config
285
311
  end
data/spec/spec_helper.rb CHANGED
@@ -1,5 +1,8 @@
1
1
  require File.dirname(__FILE__) + "/../lib/ey-flex"
2
2
 
3
+ require 'simplecov'
4
+ SimpleCov.start
5
+
3
6
  require 'fakeweb'
4
7
  require 'fakefs/safe'
5
8
  require 'randexp'