ey_cloud_server 1.4.47 → 1.4.49

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,10 +1,9 @@
1
1
  require File.dirname(__FILE__) + "/../lib/ey-flex"
2
2
 
3
- require 'ruby-debug'
4
3
  require 'fakeweb'
5
4
  require 'fakefs/safe'
6
5
  require 'randexp'
7
- require 'fog'
6
+ require 'fog/aws'
8
7
 
9
8
  # Made tests work with actual storage; better tests. - rpowell Fri Aug 5 17:53:17 PDT 2011
10
9
  #
metadata CHANGED
@@ -1,156 +1,155 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: ey_cloud_server
3
- version: !ruby/object:Gem::Version
4
- version: 1.4.47
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.4.49
5
5
  platform: ruby
6
- authors:
6
+ authors:
7
7
  - EngineYard
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
-
12
- date: 2015-05-12 00:00:00 Z
13
- dependencies:
14
- - !ruby/object:Gem::Dependency
11
+ date: 2016-07-06 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
15
14
  name: json
16
- prerelease: false
17
- requirement: &id001 !ruby/object:Gem::Requirement
18
- requirements:
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
19
17
  - - ">="
20
- - !ruby/object:Gem::Version
21
- version: 1.4.4
22
- - - <=
23
- - !ruby/object:Gem::Version
24
- version: 1.4.6
25
- type: :runtime
26
- version_requirements: *id001
27
- - !ruby/object:Gem::Dependency
28
- name: right_http_connection
29
- prerelease: false
30
- requirement: &id002 !ruby/object:Gem::Requirement
31
- requirements:
32
- - - "="
33
- - !ruby/object:Gem::Version
34
- version: 1.2.4
18
+ - !ruby/object:Gem::Version
19
+ version: 1.8.3
35
20
  type: :runtime
36
- version_requirements: *id002
37
- - !ruby/object:Gem::Dependency
38
- name: right_aws
39
21
  prerelease: false
40
- requirement: &id003 !ruby/object:Gem::Requirement
41
- requirements:
42
- - - "="
43
- - !ruby/object:Gem::Version
44
- version: 2.0.0
45
- type: :runtime
46
- version_requirements: *id003
47
- - !ruby/object:Gem::Dependency
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: 1.8.3
27
+ - !ruby/object:Gem::Dependency
48
28
  name: open4
49
- prerelease: false
50
- requirement: &id004 !ruby/object:Gem::Requirement
51
- requirements:
52
- - - ~>
53
- - !ruby/object:Gem::Version
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
54
33
  version: 1.3.0
55
34
  type: :runtime
56
- version_requirements: *id004
57
- - !ruby/object:Gem::Dependency
58
- name: nokogiri
59
35
  prerelease: false
60
- requirement: &id005 !ruby/object:Gem::Requirement
61
- requirements:
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: 1.3.0
41
+ - !ruby/object:Gem::Dependency
42
+ name: nokogiri
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
62
45
  - - ">="
63
- - !ruby/object:Gem::Version
46
+ - !ruby/object:Gem::Version
64
47
  version: 1.6.6.2
65
48
  type: :runtime
66
- version_requirements: *id005
67
- - !ruby/object:Gem::Dependency
68
- name: aws-s3
69
49
  prerelease: false
70
- requirement: &id006 !ruby/object:Gem::Requirement
71
- requirements:
72
- - - ~>
73
- - !ruby/object:Gem::Version
74
- version: 0.6.2
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: 1.6.6.2
55
+ - !ruby/object:Gem::Dependency
56
+ name: aws-s3
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: 0.6.3
75
62
  type: :runtime
76
- version_requirements: *id006
77
- - !ruby/object:Gem::Dependency
78
- name: fog
79
63
  prerelease: false
80
- requirement: &id007 !ruby/object:Gem::Requirement
81
- requirements:
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: 0.6.3
69
+ - !ruby/object:Gem::Dependency
70
+ name: fog-aws
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
82
73
  - - ">="
83
- - !ruby/object:Gem::Version
84
- version: 1.30.0
74
+ - !ruby/object:Gem::Version
75
+ version: 0.3.0
85
76
  type: :runtime
86
- version_requirements: *id007
87
- - !ruby/object:Gem::Dependency
88
- name: mysql
89
77
  prerelease: false
90
- requirement: &id008 !ruby/object:Gem::Requirement
91
- requirements:
92
- - - ~>
93
- - !ruby/object:Gem::Version
94
- version: 2.8.1
95
- type: :runtime
96
- version_requirements: *id008
97
- - !ruby/object:Gem::Dependency
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: 0.3.0
83
+ - !ruby/object:Gem::Dependency
98
84
  name: ey_enzyme
99
- prerelease: false
100
- requirement: &id009 !ruby/object:Gem::Requirement
101
- requirements:
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
102
87
  - - ">="
103
- - !ruby/object:Gem::Version
88
+ - !ruby/object:Gem::Version
104
89
  version: 1.1.7
105
90
  type: :runtime
106
- version_requirements: *id009
107
- - !ruby/object:Gem::Dependency
108
- name: ey_instance_api_client
109
91
  prerelease: false
110
- requirement: &id010 !ruby/object:Gem::Requirement
111
- requirements:
112
- - - ~>
113
- - !ruby/object:Gem::Version
114
- version: 0.1.1
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: 1.1.7
97
+ - !ruby/object:Gem::Dependency
98
+ name: ey_instance_api_client
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - "~>"
102
+ - !ruby/object:Gem::Version
103
+ version: 0.1.11
115
104
  type: :runtime
116
- version_requirements: *id010
117
- - !ruby/object:Gem::Dependency
118
- name: rake
119
105
  prerelease: false
120
- requirement: &id011 !ruby/object:Gem::Requirement
121
- requirements:
122
- - &id012
123
- - ">="
124
- - !ruby/object:Gem::Version
125
- version: "0"
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - "~>"
109
+ - !ruby/object:Gem::Version
110
+ version: 0.1.11
111
+ - !ruby/object:Gem::Dependency
112
+ name: rake
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - ">="
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
126
118
  type: :development
127
- version_requirements: *id011
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - ">="
123
+ - !ruby/object:Gem::Version
124
+ version: '0'
128
125
  description: Miscellaneous EY server utilities
129
- email:
126
+ email:
130
127
  - engineering@engineyard.com
131
- executables:
132
- - binary_log_purge
133
- - clear_binlogs_from_slave
134
- - ey-agent
128
+ executables:
135
129
  - ey-snapshots
136
130
  - eybackup
137
- - mysql_start
138
131
  extensions: []
139
-
140
132
  extra_rdoc_files: []
141
-
142
- files:
143
- - bin/binary_log_purge
144
- - bin/clear_binlogs_from_slave
145
- - bin/ey-agent
133
+ files:
134
+ - LICENSE
135
+ - README.rdoc
136
+ - Rakefile
137
+ - TODO
146
138
  - bin/ey-snapshots
147
139
  - bin/eybackup
148
- - bin/mysql_start
149
- - lib/ey-flex/big-brother.rb
140
+ - features/downloading_a_mysql_backup.feature
141
+ - features/making_a_postgresql_backup.feature
142
+ - features/restoring_postgres_backup.feature
143
+ - features/step_definitions/backups.rb
144
+ - features/step_definitions/commands.rb
145
+ - features/step_definitions/mysql.rb
146
+ - features/step_definitions/postgresql.rb
147
+ - features/support/env.rb
148
+ - lib/ey-flex.rb
150
149
  - lib/ey-flex/bucket_minder.rb
151
150
  - lib/ey-flex/ey-api.rb
152
151
  - lib/ey-flex/snapshot_minder.rb
153
- - lib/ey-flex.rb
152
+ - lib/ey_backup.rb
154
153
  - lib/ey_backup/backend.rb
155
154
  - lib/ey_backup/backup_set.rb
156
155
  - lib/ey_backup/base.rb
@@ -166,17 +165,11 @@ files:
166
165
  - lib/ey_backup/processors/gzipper.rb
167
166
  - lib/ey_backup/processors/splitter.rb
168
167
  - lib/ey_backup/spawner.rb
169
- - lib/ey_backup.rb
170
- - lib/ey_cloud_server/mysql_start.rb
171
- - lib/ey_cloud_server/version.rb
172
168
  - lib/ey_cloud_server.rb
173
- - README.rdoc
174
- - Rakefile
175
- - LICENSE
176
- - TODO
177
- - spec/big-brother_spec.rb
169
+ - lib/ey_cloud_server/version.rb
178
170
  - spec/bucket_minder_spec.rb
179
171
  - spec/config-example.yml
172
+ - spec/config.yml
180
173
  - spec/ey_api_spec.rb
181
174
  - spec/ey_backup/backend_spec.rb
182
175
  - spec/ey_backup/backup_spec.rb
@@ -190,41 +183,33 @@ files:
190
183
  - spec/helpers.rb
191
184
  - spec/snapshot_minder_spec.rb
192
185
  - spec/spec_helper.rb
193
- - features/downloading_a_mysql_backup.feature
194
- - features/making_a_postgresql_backup.feature
195
- - features/restoring_postgres_backup.feature
196
- - features/step_definitions/backups.rb
197
- - features/step_definitions/commands.rb
198
- - features/step_definitions/mysql.rb
199
- - features/step_definitions/postgresql.rb
200
- - features/support/env.rb
201
186
  homepage: http://developer.engineyard.com
202
187
  licenses: []
203
-
204
188
  metadata: {}
205
-
206
189
  post_install_message:
207
190
  rdoc_options: []
208
-
209
- require_paths:
191
+ require_paths:
210
192
  - lib
211
- required_ruby_version: !ruby/object:Gem::Requirement
212
- requirements:
213
- - *id012
214
- required_rubygems_version: !ruby/object:Gem::Requirement
215
- requirements:
216
- - *id012
193
+ required_ruby_version: !ruby/object:Gem::Requirement
194
+ requirements:
195
+ - - ">="
196
+ - !ruby/object:Gem::Version
197
+ version: '0'
198
+ required_rubygems_version: !ruby/object:Gem::Requirement
199
+ requirements:
200
+ - - ">="
201
+ - !ruby/object:Gem::Version
202
+ version: '0'
217
203
  requirements: []
218
-
219
204
  rubyforge_project:
220
- rubygems_version: 2.0.14
205
+ rubygems_version: 2.4.5.1
221
206
  signing_key:
222
207
  specification_version: 4
223
208
  summary: Server side components for Engine Yard's cloud
224
- test_files:
225
- - spec/big-brother_spec.rb
209
+ test_files:
226
210
  - spec/bucket_minder_spec.rb
227
211
  - spec/config-example.yml
212
+ - spec/config.yml
228
213
  - spec/ey_api_spec.rb
229
214
  - spec/ey_backup/backend_spec.rb
230
215
  - spec/ey_backup/backup_spec.rb
@@ -1,263 +0,0 @@
1
- #!/usr/bin/env ruby
2
-
3
- # Filename: binary_log_purge.rb
4
- # Author: Tyler Poland
5
- # Version: 0.2
6
- # Purpose: Script to check current state of all replica databases and
7
- # purge binary logs from the master based on the position of any
8
- # and all replica databases.
9
-
10
- # Changelog 0.1 -> 0.2
11
- # - modified binlog check routine to lookup binary log storage in configuration file instead of relying on
12
- # binary logs being stored in the data directory
13
-
14
- # Changelog 0.2 -> 0.3
15
- # - Added ability to purge binary logs for standalone master databases
16
-
17
- # Changelog 0.3 -> 0.4
18
- # - Added support for remote tunneled slave with reverse connection on port 13306
19
-
20
- # Changelog 0.4 -> 1.0
21
- # - Add automatic create user for master to connect to replica
22
-
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
26
-
27
- require 'rubygems'
28
- require 'net/smtp'
29
- require 'yaml'
30
- require 'open3'
31
- require 'getoptlong'
32
-
33
- # Set up logging functions based on desired verbosity level
34
- def log_info(message) # may get redefined below
35
- puts message
36
- end
37
-
38
- def log_error(message)
39
- STDERR.write(message + "\n")
40
- end
41
-
42
- opts = GetoptLong.new(['--quiet', '-q', GetoptLong::NO_ARGUMENT])
43
- opts.each do |opt, arg|
44
- if opt == '--quiet'
45
- def log_info(_) end
46
- end
47
- end
48
-
49
-
50
- log_info Time.now
51
- # Conditional require for JSON if dna file exists
52
- chef_file = '/etc/chef/dna.json'
53
- if File.exists?(chef_file)
54
- require 'rubygems'
55
- require 'json'
56
- end
57
-
58
- # Modify default purge count
59
- keep_logs = 5
60
- binpurge_config = '/etc/engineyard/binlogpurge.yml'
61
- if File.exists?(binpurge_config)
62
- options = YAML::load(File.read(binpurge_config))
63
- if options['keep'] > 0
64
- keep_logs = options['keep']
65
- log_info "Overriding keep logs from configuration file"
66
- end
67
- end
68
-
69
- # function to send error emails
70
- def failure_message(message)
71
- sender = "Database Team <db@engineyard.com"
72
- recipients = "db@engineyard.com"
73
- hostname = `hostname`.chomp
74
- subject = "An error has occurred while purging binary logs on #{hostname}"
75
- mailtext = <<EOF
76
- From: #{sender}
77
- To: #{recipients}
78
- Subject: #{subject}
79
- #{message}
80
- EOF
81
-
82
- begin Net::SMTP.start('mail') do |smtp|
83
- smtp.sendmail(mailtext, 'root@' + hostname, recipients)
84
- end
85
- rescue Exception => e
86
- log_error "Exception occurred: " + e
87
- end
88
-
89
- exit(1)
90
- end
91
-
92
- # function to retrieve password from .mytop file
93
- def get_password
94
- dbpass = %x{cat /root/.mytop |grep pass |awk -F= '{print $2}'}.chomp
95
- failure_message() if dbpass.length < 1
96
- dbpass
97
- end
98
-
99
- # function to run query against database
100
- def run_query(host, user, password, query)
101
- options = ''
102
- if host == '127.0.0.1'
103
- options = options + ' -P13306'
104
- end
105
- if query == 'show processlist'
106
- stdin, stdout, stderr = Open3.popen3("mysql -u#{user} -p#{password} #{options} -h#{host} -N -e\"#{query}\"|grep 'Binlog'")
107
- else
108
- stdin, stdout, stderr = Open3.popen3("mysql -u#{user} -p#{password} #{options} -h#{host} -e\"#{query}\"")
109
- end
110
- query_error = stderr.read
111
- if query_error.length > 0
112
- log_error "Error caught: #{query_error}"
113
- test_add_privilege(user, password, query_error)
114
- exit 0
115
- end
116
- result = stdout.read
117
- stdin.close
118
- stdout.close
119
- stderr.close
120
- result
121
- end
122
-
123
- # function to test for user privilege
124
- def test_add_privilege(user, password, error)
125
- full_hostname = %x{hostname --long}.chomp
126
- dns_name = %x{hostname -d}.chomp
127
- # verify that this is the user privilege error with the root user not having access to the replica
128
- if error.match(/ERROR 1045.* Access denied for user 'root'@'.*#{dns_name}' \(using password: YES\)/)
129
- # check the master to see if grant based on hostname or IP exists
130
- master_ip = %x{hostname -i}.chomp.gsub(/\s+/,'')
131
- stdin, stdout, stderr = Open3.popen3("mysql -u#{user} -p#{password} -e\"show grants for 'root'@'#{master_ip}'\"")
132
- master_ip_error = stderr.read
133
-
134
- stdin, stdout, stderr = Open3.popen3("mysql -u#{user} -p#{password} -e\"show grants for 'root'@'#{full_hostname}'\"")
135
- full_hostname_error = stderr.read
136
-
137
- regex = 'ERROR 1141.*There is no such grant defined'
138
- if master_ip_error.match(/#{regex}/) || full_hostname_error.match(/#{regex}/)
139
- # neither grant is defined on the master so go ahead and add it
140
- log_info "The user privilege does not exist on the master, the script will now create it."
141
- log_info "This privilege must propagate to the replica via replication, the user may not be available for immediate use."
142
- stdin, stdout, stderr = Open3.popen3("mysql -u#{user} -p#{password} -e\"grant all privileges on *.* to 'root'@'#{master_ip}' identified by '#{password}'\"")
143
- create_user_error = stderr.read
144
- if create_user_error.length > 0
145
- log_error "Unable to create user: #{create_user_error}"
146
- exit 1
147
- end
148
- else
149
- log_error "The required privilege appears to exist on the master, you may need to wait for replication to process the grant on the Replica"
150
- exit 0
151
- end
152
- end
153
- end
154
-
155
- # function to convert input into yaml
156
- def yaml_result(file)
157
- parse = file.gsub(/^\*.*$/,'').gsub(/^/,' ').gsub(/^\s+/, ' ')
158
- yml = YAML.load(parse)
159
- end
160
-
161
- # parse the hostname out of the processlist
162
- def extract_host(line)
163
- line =~ /.+\s+(.+):.+/
164
- $1
165
- end
166
-
167
- # function to get replica position from replica host
168
- def slave_log_file(hostname, user, pass)
169
- if hostname == 'localhost'
170
- hostname = '127.0.0.1'
171
- end
172
-
173
- q_result = run_query(hostname, user, pass, "show slave status\\G")
174
- if q_result.match(/.*Slave_SQL_Running: No.*/)
175
- log_error "Slave SQL thread is not running."
176
- log_info "The error is: \n#{q_result}"
177
- log_error "Unable to continue; exiting!"
178
- exit 1
179
- end
180
-
181
- yaml = yaml_result(q_result)
182
- yaml["Relay_Master_Log_File"]
183
- end
184
-
185
- dbuser = 'root'
186
-
187
- if not dbpassword = get_password
188
- failure_message("Password not found for slice, check for /root/.mytop")
189
- end
190
-
191
- mysql_process = %x{ps -ef|grep '[m]ysqld'}.split(/\s+/).select{|item| item.match(/^--/)}
192
- mysql_params = Hash.new
193
- mysql_process.each {|i| k, v = i.split('='); mysql_params[k]=v}
194
- datadir = mysql_params['--datadir']
195
- config_file = mysql_params['--defaults-file']
196
- binlog_dir = File.dirname(%x{cat #{config_file} |egrep '^log-bin'|grep -v '.index'|awk -F= '{print $2}'}.gsub(/\s+/,'').chomp)
197
-
198
-
199
- # If master-bin.000001 exists then only purge logs if disk space is constrained
200
- binary_log_name = %x{cat #{config_file}|grep '^log-bin'|grep -v 'index' |awk -F= '{print $2}'}.gsub(/\s/,'')
201
- if binary_log_name == ''
202
- log_info "log-bin not set in config file, host does not have master role, unable to proceed"
203
- exit(0)
204
- end
205
- if File.exists?(binary_log_name + '.000001')
206
- purge_threshold = 90
207
- if %x{df -h |egrep "/db" |awk '{print $5}'}.to_i < purge_threshold
208
- log_info "The first binary log exists and the purge threshold has not been reached; skipping purge action"
209
- exit(0)
210
- end
211
- end
212
-
213
- # Check master for all connected replication slaves
214
- result = run_query('localhost', dbuser, dbpassword, 'show processlist')
215
- slave_hosts = []
216
- min_log = 0
217
- result.each do |line|
218
- if line.include? 'Binlog Dump'
219
- slave = Hash.new
220
- slave["hostname"] = extract_host(line)
221
- slave["Relay_Master_Log_File"] = slave_log_file(slave["hostname"], dbuser, dbpassword)
222
- slave["Relay_Master_Log_File"] =~ /\w+.(\d{6})/ and min_log = $1.to_i if $1.to_i < min_log || min_log == 0
223
- log_info "Slave Hostname: #{slave["hostname"]}, Relay_Master_log: #{slave["Relay_Master_Log_File"]}"
224
- slave_hosts << slave
225
- end
226
- end
227
-
228
- # stop log purge #{keep_logs} logs before the current read position
229
- stop_log = min_log - keep_logs
230
-
231
- # if standalone master and no replicas are found we stop purge #{keep_logs} logs before master's current position
232
- if min_log == 0 and File.exists?(chef_file)
233
- chef_config = JSON.parse(File.read(chef_file))
234
- if chef_config['db_slaves'].empty? or chef_config['db_slaves'].nil?
235
- current_master = %x{cd #{binlog_dir} && ls -tr master-bin.[0-9]* | tail -n 1}
236
- current_master =~ /\w+.(\d{6})/ and stop_log = $1.to_i + 1 - keep_logs
237
- elsif min_log == 0
238
- log_error "Slave is on record as '#{chef_config['db_slaves']}' but replication is not running."
239
- exit 1
240
- end
241
- end
242
-
243
-
244
- # Purge logs based on minimum position of all servers
245
- min_master_log = %x{cd #{binlog_dir} && ls -tr master-bin.[0-9]* | head -n 1}
246
- min_master_log =~ /\w+.(\d{6})/ and min_master_num = $1.to_i + 1
247
-
248
- min_master_num.upto(min_master_num + 10) do |i|
249
- # purge up to 10 files as long as the top file is less than the minimum replica log
250
- if stop_log < 0
251
- log_error "Could not verify replication status, confirm that replication is running. Exiting!"
252
- break
253
- elsif i >= stop_log + 1
254
- log_info "File number of #{i} exceeds minimum purge file of #{stop_log + 1} based on keeping #{keep_logs} files. Exiting!"
255
- break
256
- end
257
- file = "master-bin.%06d" % i
258
- log_info "Purging binary logs to #{file}"
259
- run_query('localhost', dbuser, dbpassword, "purge master logs to '#{file}'")
260
- sleep 120
261
- end
262
-
263
- log_info Time.now