virtualmonkey 0.0.1

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.
Files changed (178) hide show
  1. data/.document +5 -0
  2. data/LICENSE +20 -0
  3. data/README.rdoc +77 -0
  4. data/Rakefile +51 -0
  5. data/VERSION +1 -0
  6. data/bin/grinder +102 -0
  7. data/bin/mcicp +46 -0
  8. data/bin/monkey +12 -0
  9. data/bin/vary_instance_types +59 -0
  10. data/config/cloud_variables/all_clouds.json +30 -0
  11. data/config/cloud_variables/east.json +9 -0
  12. data/config/cloud_variables/rackspace.json +7 -0
  13. data/config/cloud_variables/west.json +9 -0
  14. data/config/common_inputs/apache_haproxy.json +27 -0
  15. data/config/common_inputs/base.json +5 -0
  16. data/config/common_inputs/ebs_toolbox.json +10 -0
  17. data/config/common_inputs/haproxy.json +15 -0
  18. data/config/common_inputs/lamp.json +30 -0
  19. data/config/common_inputs/mysql.json +24 -0
  20. data/config/common_inputs/none.json +4 -0
  21. data/config/common_inputs/php.json +25 -0
  22. data/config/common_inputs/php_aio_trial_chef_alpha.json +3 -0
  23. data/config/common_inputs/php_app_fe_chef.json +12 -0
  24. data/config/common_inputs/php_elb.json +12 -0
  25. data/config/common_inputs/qstart.json +5 -0
  26. data/config/common_inputs/rails.json +31 -0
  27. data/config/common_inputs/rails_aio_demo_chef_alpha.json +3 -0
  28. data/config/common_inputs/rails_aio_developer_chef_alpha.json +10 -0
  29. data/config/common_inputs/rsgrid.json +10 -0
  30. data/config/common_inputs/tomcat.json +15 -0
  31. data/config/common_inputs/windows_blog_engine.json +3 -0
  32. data/config/common_inputs/windows_net_aio.json +14 -0
  33. data/config/troop/11H1/backup/base.json +10 -0
  34. data/config/troop/11H1/backup/lamp_mysql_50.json +10 -0
  35. data/config/troop/11H1/backup/lamp_mysql_51.json +10 -0
  36. data/config/troop/11H1/backup/loadbalancer-php.json +13 -0
  37. data/config/troop/11H1/backup/loadbalancer.json +14 -0
  38. data/config/troop/11H1/backup/loadbalancer_rails.json +13 -0
  39. data/config/troop/11H1/backup/loadbalancer_tomcat6.json +13 -0
  40. data/config/troop/11H1/backup/mysql50.json +11 -0
  41. data/config/troop/11H1/backup/mysql50_toolbox.json +12 -0
  42. data/config/troop/11H1/backup/mysql51.json +11 -0
  43. data/config/troop/11H1/backup/mysql51_toolbox.json +12 -0
  44. data/config/troop/11H1/backup/php_elb.json +11 -0
  45. data/config/troop/11H1/base.json +10 -0
  46. data/config/troop/11H1/ebs_toolbox.json +12 -0
  47. data/config/troop/11H1/lamp_mysql_50.json +10 -0
  48. data/config/troop/11H1/lamp_mysql_51.json +10 -0
  49. data/config/troop/11H1/loadbalancer-php.json +13 -0
  50. data/config/troop/11H1/loadbalancer.json +17 -0
  51. data/config/troop/11H1/loadbalancer_rails.json +13 -0
  52. data/config/troop/11H1/loadbalancer_tomcat6.json +13 -0
  53. data/config/troop/11H1/mysql50.json +11 -0
  54. data/config/troop/11H1/mysql50_toolbox.json +12 -0
  55. data/config/troop/11H1/mysql51.json +11 -0
  56. data/config/troop/11H1/mysql51_awsdns.json +11 -0
  57. data/config/troop/11H1/mysql51_debug.json +11 -0
  58. data/config/troop/11H1/mysql51_toolbox.json +12 -0
  59. data/config/troop/11H1/php.json +13 -0
  60. data/config/troop/11H1/php_elb.json +11 -0
  61. data/config/troop/11H1/rails.json +13 -0
  62. data/config/troop/11H1/tomcat6.json +13 -0
  63. data/config/troop/chef_quickstart.json +10 -0
  64. data/config/troop/just_elb +10 -0
  65. data/config/troop/lamp_v4.json +10 -0
  66. data/config/troop/patch_test.json +10 -0
  67. data/config/troop/rightlink.json +10 -0
  68. data/config/troop/simple_fail.json +11 -0
  69. data/config/troop/simple_pass.json +11 -0
  70. data/config/troop/windows_blog_engine.json +10 -0
  71. data/config/troop/windows_net_aio.json +10 -0
  72. data/config/troop/windows_quick_start.json +10 -0
  73. data/features/base.rb +31 -0
  74. data/features/db_toolbox.rb +59 -0
  75. data/features/ebs_toolbox.rb +62 -0
  76. data/features/lamp.rb +33 -0
  77. data/features/lb-apache-haproxy.rb +49 -0
  78. data/features/mysql_5.x_v2_v4_from_scratch.rb +71 -0
  79. data/features/mysql_5.x_v2_v4_from_scratch_awsdns.rb +71 -0
  80. data/features/mysql_5.x_v2_v4_from_scratch_dyndns.rb +71 -0
  81. data/features/mysql_v1_upgrade_v2.rb +54 -0
  82. data/features/old_cuke_features/Rakefile +121 -0
  83. data/features/old_cuke_features/Steps-TODO +31 -0
  84. data/features/old_cuke_features/app_state.feature +25 -0
  85. data/features/old_cuke_features/app_test.feature +24 -0
  86. data/features/old_cuke_features/base.feature +16 -0
  87. data/features/old_cuke_features/chef_quickstart.feature +11 -0
  88. data/features/old_cuke_features/db_toolbox.feature +38 -0
  89. data/features/old_cuke_features/ebs_toolbox.feature +39 -0
  90. data/features/old_cuke_features/elb_create_delete.feature +41 -0
  91. data/features/old_cuke_features/elb_generic.feature +27 -0
  92. data/features/old_cuke_features/fe_app_checks.feature +21 -0
  93. data/features/old_cuke_features/just-start.feature +13 -0
  94. data/features/old_cuke_features/lamp.feature +15 -0
  95. data/features/old_cuke_features/lb-apache-haproxy.feature +27 -0
  96. data/features/old_cuke_features/mysql_5.x_v2_v4_from_scratch.feature +33 -0
  97. data/features/old_cuke_features/mysql_5.x_v2_v4_from_scratch_awsdns.feature +33 -0
  98. data/features/old_cuke_features/mysql_5.x_v2_v4_from_scratch_dyndns.feature +33 -0
  99. data/features/old_cuke_features/mysql_chef_premium.feature +27 -0
  100. data/features/old_cuke_features/mysql_chef_premium_from_scratch.feature +37 -0
  101. data/features/old_cuke_features/mysql_v1_upgrade_v2.feature +42 -0
  102. data/features/old_cuke_features/php.feature +27 -0
  103. data/features/old_cuke_features/php_aio_trial_chef_alpha.feature +11 -0
  104. data/features/old_cuke_features/php_chef.feature +21 -0
  105. data/features/old_cuke_features/php_elb.feature +41 -0
  106. data/features/old_cuke_features/rails.feature +26 -0
  107. data/features/old_cuke_features/rails_aio_developer_chef.feature +17 -0
  108. data/features/old_cuke_features/reboot.feature +23 -0
  109. data/features/old_cuke_features/rightlink.feature +19 -0
  110. data/features/old_cuke_features/rsgrid.feature +19 -0
  111. data/features/old_cuke_features/simple.feature +8 -0
  112. data/features/old_cuke_features/simple_fail.feature +9 -0
  113. data/features/old_cuke_features/start-stop.feature +13 -0
  114. data/features/old_cuke_features/step_definitions/app.rb +21 -0
  115. data/features/old_cuke_features/step_definitions/deployment_steps.rb +112 -0
  116. data/features/old_cuke_features/step_definitions/ebs.rb +36 -0
  117. data/features/old_cuke_features/step_definitions/elb.rb +35 -0
  118. data/features/old_cuke_features/step_definitions/lb.rb +22 -0
  119. data/features/old_cuke_features/step_definitions/mysql_steps.rb +84 -0
  120. data/features/old_cuke_features/terminate.feature +7 -0
  121. data/features/old_cuke_features/tomcat6-tests-TODO +29 -0
  122. data/features/old_cuke_features/tomcat6.feature +27 -0
  123. data/features/patch_test.rb +33 -0
  124. data/features/php.rb +54 -0
  125. data/features/php_elb.rb +78 -0
  126. data/features/rails.rb +54 -0
  127. data/features/start_only.rb +26 -0
  128. data/features/tomcat6.rb +54 -0
  129. data/lib/virtualmonkey.rb +28 -0
  130. data/lib/virtualmonkey/application.rb +75 -0
  131. data/lib/virtualmonkey/application_frontend.rb +42 -0
  132. data/lib/virtualmonkey/command.rb +39 -0
  133. data/lib/virtualmonkey/command/clone.rb +50 -0
  134. data/lib/virtualmonkey/command/create.rb +21 -0
  135. data/lib/virtualmonkey/command/destroy.rb +51 -0
  136. data/lib/virtualmonkey/command/list.rb +10 -0
  137. data/lib/virtualmonkey/command/run.rb +76 -0
  138. data/lib/virtualmonkey/command/troop.rb +146 -0
  139. data/lib/virtualmonkey/cuke_monk.rb +184 -0
  140. data/lib/virtualmonkey/deployment_monk.rb +132 -0
  141. data/lib/virtualmonkey/deployment_runner.rb +333 -0
  142. data/lib/virtualmonkey/ebs.rb +161 -0
  143. data/lib/virtualmonkey/ebs_runner.rb +59 -0
  144. data/lib/virtualmonkey/elb_runner.rb +194 -0
  145. data/lib/virtualmonkey/fe_app_runner.rb +7 -0
  146. data/lib/virtualmonkey/file_locations.rb +7 -0
  147. data/lib/virtualmonkey/frontend.rb +124 -0
  148. data/lib/virtualmonkey/http_checks.rb +33 -0
  149. data/lib/virtualmonkey/index.html.erb +109 -0
  150. data/lib/virtualmonkey/lamp_runner.rb +29 -0
  151. data/lib/virtualmonkey/mysql.rb +172 -0
  152. data/lib/virtualmonkey/mysql_runner.rb +108 -0
  153. data/lib/virtualmonkey/mysql_toolbox_runner.rb +51 -0
  154. data/lib/virtualmonkey/patch_runner.rb +46 -0
  155. data/lib/virtualmonkey/php_aio_trial_chef_runner.rb +6 -0
  156. data/lib/virtualmonkey/php_chef_runner.rb +69 -0
  157. data/lib/virtualmonkey/rails_aio_developer_chef_runner.rb +8 -0
  158. data/lib/virtualmonkey/shared_dns.rb +67 -0
  159. data/lib/virtualmonkey/simple.rb +5 -0
  160. data/lib/virtualmonkey/simple_runner.rb +6 -0
  161. data/lib/virtualmonkey/test_case_interface.rb +151 -0
  162. data/lib/virtualmonkey/unified_application.rb +40 -0
  163. data/spec/bug3518.rb +16 -0
  164. data/spec/concurrent_writes_spec.rb +26 -0
  165. data/spec/cuke_job_spec.rb +26 -0
  166. data/spec/ek.rb +28 -0
  167. data/spec/little_ruby.rb +20 -0
  168. data/spec/mini.rb +25 -0
  169. data/spec/monitoring.rb +13 -0
  170. data/spec/release_aws_dns.rb +5 -0
  171. data/spec/release_dns.rb +5 -0
  172. data/spec/release_dyndns.rb +5 -0
  173. data/spec/shared_resources_spec.rb +25 -0
  174. data/spec/spec.opts +1 -0
  175. data/spec/spec_helper.rb +11 -0
  176. data/spec/virtualmonkey_spec.rb +7 -0
  177. data/virtualmonkey.gemspec +265 -0
  178. metadata +428 -0
@@ -0,0 +1,333 @@
1
+ module VirtualMonkey
2
+ module DeploymentRunner
3
+ include VirtualMonkey::TestCaseInterface
4
+ attr_accessor :deployment, :servers
5
+ attr_accessor :scripts_to_run
6
+
7
+ def initialize(deployment)
8
+ @deployment = Deployment.find_by_nickname_speed(deployment).first
9
+ raise "Fatal: Could not find a deployment named #{deployment}" unless @deployment
10
+ @servers = @deployment.servers_no_reload
11
+ @scripts_to_run = {}
12
+ @rerun_last_command = []
13
+ lookup_scripts
14
+ @servers.each { |s| s.settings }
15
+ end
16
+
17
+ # It's not that I'm a Java fundamentalist; I merely believe that mortals should
18
+ # not be calling the following methods directly. Instead, they should use the
19
+ # TestCaseInterface methods (behavior, verify, probe) to access these functions.
20
+ # Trust me, I know what's good for you. -- Tim R.
21
+ private
22
+
23
+ def lookup_scripts
24
+ puts "WARNING: lookup_scripts is undefined, this must be set in mixin classes"
25
+ scripts = [
26
+ [ 'script_ref1', 'name' ],
27
+ [ 'script_ref2', 'name' ]
28
+ ]
29
+ # st = ServerTemplate.find(s_two.server_template_href)
30
+ # lookup_scripts_table(st,scripts)
31
+ end
32
+
33
+ def lookup_scripts_table(st,table)
34
+ table.each { |a|
35
+ @scripts_to_run[ a[0] ] = st.executables.detect { |ex| ex.name =~ /#{a[1]}/ }
36
+ raise "FATAL: Script #{a[1]} not found" unless @scripts_to_run[ a[0] ]
37
+ }
38
+ end
39
+
40
+ def s_one
41
+ @servers[0]
42
+ end
43
+
44
+ def s_two
45
+ @servers[1]
46
+ end
47
+
48
+ def s_three
49
+ @servers[2]
50
+ end
51
+
52
+ def s_four
53
+ @servers[3]
54
+ end
55
+
56
+ # Launch all servers in the deployment.
57
+ def launch_all
58
+ @servers.each { |s|
59
+ begin
60
+ object_behavior(s, :start)
61
+ rescue Exception => e
62
+ raise e unless e.message =~ /AlreadyLaunchedError/
63
+ end
64
+ }
65
+ end
66
+
67
+ # sets the MASTER_DB_DNSNAME to this machine's ip address
68
+ def set_master_db_dnsname
69
+ the_name = get_tester_ip_addr
70
+ @deployment.set_input("MASTER_DB_DNSNAME", the_name)
71
+ @deployment.set_input("DB_HOST_NAME", the_name)
72
+ end
73
+
74
+ # Helper method, performs selection of a subset of servers to operate on based on the server's nicknames.
75
+ # * nickname_substr<~String> - regex compatible string to match
76
+ def select_set(nickname_substr)
77
+ @servers.select { |s| s.nickname =~ /#{nickname_substr}/ }
78
+ end
79
+
80
+ # Launch server(s) that match nickname_substr
81
+ # * nickname_substr<~String> - regex compatible string to match
82
+ def launch_set(nickname_substr)
83
+ set = select_set(nickname_substr)
84
+ set.each { |s|
85
+ begin
86
+ object_behavior(s, :start)
87
+ rescue Exception => e
88
+ raise e unless e.message =~ /AlreadyLaunchedError/
89
+ end
90
+ }
91
+ end
92
+
93
+ # Re-Launch all server
94
+ def relaunch_all
95
+ @servers.each { |s|
96
+ begin
97
+ object_behavior(s, :relaunch)
98
+ rescue Exception => e
99
+ raise e #unless e.message =~ /AlreadyLaunchedError/
100
+ end
101
+ }
102
+ end
103
+
104
+ # un-set all tags on all servers in the deployment
105
+ def unset_all_tags
106
+ @deployment.servers_no_reload.each do |s|
107
+ # can't unset ALL tags, so we must set a bogus one
108
+ s.tags = [{"name"=>"removeme:now=1"}]
109
+ s.save
110
+ end
111
+ end
112
+
113
+ # Wait for server(s) matching nickname_substr to enter state
114
+ # * nickname_substr<~String> - regex compatible string to match
115
+ # * state<~String> - state to wait for, eg. operational
116
+ def wait_for_set(nickname_substr, state)
117
+ set = select_set(nickname_substr)
118
+ state_wait(set, state)
119
+ end
120
+
121
+ # Wait for server(s) matching nickname_substr to enter state
122
+ # * servers<~Array> - Array of Servers to wait on
123
+ # * state<~String> - state to wait for, eg. operational
124
+ def wait_for_servers(servers, state)
125
+ state_wait(set, state)
126
+ end
127
+
128
+ # Helper method, waits for state on a set of servers.
129
+ # * set<~Array> of servers to operate on
130
+ # * state<~String> state to wait for
131
+ def state_wait(set, state)
132
+ # do a special wait, if waiting for operational (for dns)
133
+ if state == "operational"
134
+ set.each { |server| server.wait_for_operational_with_dns }
135
+ else
136
+ set.each { |server| server.wait_for_state(state) }
137
+ end
138
+ end
139
+
140
+ # Wait for all server(s) to enter state.
141
+ # * state<~String> - state to wait for, eg. operational
142
+ def wait_for_all(state)
143
+ state_wait(@servers, state)
144
+ end
145
+
146
+ def start_ebs_all(wait=true)
147
+ @servers.each { |s| s.start_ebs }
148
+ wait_for_all("operational") if wait
149
+ @servers.each { |s|
150
+ s.dns_name = nil
151
+ s.private_dns_name = nil
152
+ }
153
+ end
154
+
155
+ def stop_ebs_all(wait=true)
156
+ @servers.each { |s| s.stop_ebs }
157
+ wait_for_all("stopped") if wait
158
+ @servers.each { |s|
159
+ s.dns_name = nil
160
+ s.private_dns_name = nil
161
+ }
162
+ end
163
+
164
+ def stop_all(wait=true)
165
+ @servers.each { |s| s.stop }
166
+ wait_for_all("stopped") if wait
167
+ @servers.each { |s|
168
+ s.dns_name = nil
169
+ s.private_dns_name = nil
170
+ }
171
+ end
172
+
173
+ def reboot_all(serially_reboot = false)
174
+ wait_for_reboot = true
175
+ # Do NOT thread this each statement
176
+ @servers.each do |s|
177
+ object_behavior(s, :reboot, wait_for_reboot)
178
+ if serially_reboot
179
+ object_behavior(s, :wait_for_state, "operational")
180
+ end
181
+ end
182
+ @servers.each do |s|
183
+ object_behavior(s, :wait_for_state, "operational")
184
+ end
185
+ end
186
+
187
+ # Run a script on server in the deployment
188
+ # * server<~Server> the server to run the script on
189
+ # * friendly_name<~String> string lookup for Hash @scripts_to_run. @scripts_to_run must be a Hash containing an Executable with this key.
190
+ def run_script(friendly_name, server)
191
+ audit = server.run_executable(@scripts_to_run[friendly_name])
192
+ audit.wait_for_completed
193
+ end
194
+
195
+
196
+ # Detect operating system on each server and stuff the corresponding values for platform into the servers params (for temp storage only)
197
+ def detect_os
198
+ @server_os = Array.new
199
+ @servers.each do |server|
200
+ if object_behavior(server, :spot_check_command?, "lsb_release -is | grep Ubuntu")
201
+ puts "setting server to ubuntu"
202
+ server.os = "ubuntu"
203
+ server.apache_str = "apache2"
204
+ server.apache_check = "apache2ctl status"
205
+ server.haproxy_check = "service haproxy status"
206
+ else
207
+ puts "setting server to centos"
208
+ server.os = "centos"
209
+ server.apache_str = "httpd"
210
+ server.apache_check = "service httpd status"
211
+ server.haproxy_check = "service haproxy check"
212
+ end
213
+ end
214
+ end
215
+
216
+ # Assumes the host machine is EC2, uses the meta-data to grab the IP address of this
217
+ # 'tester server' eg. used for the input variation MASTER_DB_DNSNAME
218
+ def get_tester_ip_addr
219
+ if File.exists?("/var/spool/ec2/meta-data.rb")
220
+ require "/var/spool/ec2/meta-data-cache"
221
+ else
222
+ ENV['EC2_PUBLIC_HOSTNAME'] = "127.0.0.1"
223
+ end
224
+ my_ip_input = "text:"
225
+ my_ip_input += ENV['EC2_PUBLIC_HOSTNAME']
226
+ my_ip_input
227
+ end
228
+
229
+ # Log rotation
230
+ def force_log_rotation(server)
231
+ response = server.spot_check_command?('logrotate -f /etc/logrotate.conf')
232
+ raise "Logrotate restart failed" unless response
233
+ end
234
+
235
+ def log_check(server, logfile)
236
+ response = nil
237
+ count = 0
238
+ until response || count > 3 do
239
+ response = server.spot_check_command?("test -f #{logfile}")
240
+ break if response
241
+ count += 1
242
+ sleep 10
243
+ end
244
+ raise "Log file does not exist: #{logfile}" unless response
245
+ end
246
+
247
+ # Checks that monitoring is enabled on all servers in the deployment. Will raise an error if monitoring is not enabled.
248
+ def check_monitoring
249
+ @servers.each do |server|
250
+ server.settings
251
+ response = nil
252
+ count = 0
253
+ until response || count > 20 do
254
+ begin
255
+ response = server.monitoring
256
+ rescue
257
+ response = nil
258
+ count += 1
259
+ sleep 10
260
+ end
261
+ end
262
+ raise "Fatal: Failed to verify that monitoring is operational" unless response
263
+ #TODO: pass in some list of plugin info to check multiple values. For now just
264
+ # hardcoding the cpu check
265
+ sleep 60 # This is to allow monitoring data to accumulate
266
+ monitor=server.get_sketchy_data({'start'=>-60,'end'=>-20,'plugin_name'=>"cpu-0",'plugin_type'=>"cpu-idle"})
267
+ idle_values = monitor['data']['value']
268
+ raise "No cpu idle data" unless idle_values.length > 0
269
+ raise "No idle time" unless idle_values[0] > 0
270
+ puts "Monitoring is OK for #{server.nickname}"
271
+ end
272
+ end
273
+
274
+
275
+
276
+ # TODO - we do not know what the RS_INSTANCE_ID available to the testing.
277
+ # For now we are checking at a high level that the services are working
278
+ # and then assume that the config file changes done during start are
279
+ # correct for the new instance data.
280
+ #
281
+ def perform_start_stop_operations
282
+ behavior(:detect_os)
283
+ s=@servers.first
284
+ # Save configuration files for comparison after starting
285
+ behavior(:save_configuration_files, s)
286
+ # Stop the servers
287
+ behavior(:stop_ebs_all)
288
+ # Verify all stopped
289
+ # Start the servers
290
+ behavior(:start_ebs_all, true)
291
+ # Do this for all? Or just the one?
292
+ # @servers.each { |server| server.wait_for_operational_with_dns }
293
+ s=@servers.first
294
+ object_behavior(s, :wait_for_operational_with_dns)
295
+ # Verify operational
296
+ behavior(:run_simple_check, s)
297
+ end
298
+
299
+ # TODO there will be other files that need compares et al. Create a list
300
+ # of them and abstarct the tests
301
+ # Copy configuration files into some location for usage after start
302
+ def save_configuration_files(server)
303
+ puts "Saving config files"
304
+ object_behavior(server, :spot_check_command, 'mkdir -p /root/start_stop_backup')
305
+ object_behavior(server, :spot_check_command, 'cp /etc/postfix/main.cf /root/start_stop_backup/.')
306
+ object_behavior(server, :spot_check_command, 'cp /etc/syslog-ng/syslog-ng.conf /root/start_stop_backup/.')
307
+ end
308
+
309
+ # Diff the new config file with the saved one and check that the only
310
+ # line that is different is the one that has the mydestination change
311
+ def test_mail_config(server)
312
+ res = server.spot_check_command('diff /etc/postfix/main.cf /root/start_stop_backup/main.cf')
313
+ # This is lame - assuming if the file is modified then it's okay
314
+ raise "ERROR: postfix main.cf configuration file did not change when restarted" unless res
315
+ end
316
+
317
+ def test_syslog_config(server)
318
+ res = server.spot_check_command('diff /etc/syslog-ng/syslog-ng.conf /root/start_stop_backup/syslog-ng.conf')
319
+ # This is lame - assuming if the file is modified then it's okay
320
+ raise "ERROR: syslog-ng configuration file did not change when restarted" unless res
321
+ end
322
+
323
+ def run_simple_checks
324
+ @servers.each { |s| behavior(:run_simple_check, s) }
325
+ end
326
+
327
+ # this is where ALL the generic application server checks live, this could get rather long but for now it's a single method with a sequence of checks
328
+ def run_simple_check(server)
329
+ behavior(:test_mail_config, server)
330
+ behavior(:test_syslog_config, server)
331
+ end
332
+ end
333
+ end
@@ -0,0 +1,161 @@
1
+ module VirtualMonkey
2
+ module EBS
3
+ include VirtualMonkey::DeploymentRunner
4
+ attr_accessor :stripe_count
5
+ attr_accessor :volume_size
6
+ attr_accessor :mount_point
7
+ attr_accessor :lineage
8
+
9
+ # sets the stripe count for the deployment
10
+ # * count<~String> eg. "3"
11
+ def set_variation_stripe_count(count)
12
+ @stripe_count = count
13
+ @deployment.set_input("EBS_STRIPE_COUNT", "text:#{@stripe_count}")
14
+ end
15
+
16
+ # sets the volume size n GB for the runner
17
+ # * kind<~Num>
18
+ def set_variation_volume_size(size)
19
+ @volume_size = size
20
+ end
21
+
22
+ # sets the EBS mount point for the runner
23
+ # * kind<~String>
24
+ def set_variation_mount_point(mnt)
25
+ @mount_point = mnt
26
+ end
27
+
28
+ # sets the lineage for the deployment
29
+ # * kind<~String> can be "chef" or nil
30
+ def set_variation_lineage(kind = nil)
31
+ @lineage = "testlineage#{@deployment.href.split(/\//).last}"
32
+ if kind
33
+ raise "Only support nil kind for ebs lineage"
34
+ else
35
+ @deployment.set_input('EBS_LINEAGE', "text:#{@lineage}")
36
+ # unset all server level inputs in the deployment to ensure use of
37
+ # the setting from the deployment level
38
+ @deployment.servers_no_reload.each do |s|
39
+ s.set_input('EBS_LINEAGE', "text:")
40
+ end
41
+ end
42
+ end
43
+
44
+ # take the lineage name, find all snapshots and sleep until none are in the pending state.
45
+ def wait_for_snapshots
46
+ timeout=1500
47
+ step=10
48
+ while timeout > 0
49
+ puts "Checking for snapshot completed"
50
+ snapshots = behavior(:find_snapshots)
51
+ status= snapshots.map { |x| x.aws_status }
52
+ break unless status.include?("pending")
53
+ sleep step
54
+ timeout -= step
55
+ end
56
+ raise "FATAL: timed out waiting for all snapshots in lineage #{@lineage} to complete" if timeout == 0
57
+ end
58
+
59
+ # Find all snapshots associated with this deployment's lineage
60
+ def find_snapshots
61
+ unless @lineage
62
+ s = @servers.first
63
+ kind_params = s.transform_parameters(s.parameters)
64
+ @lineage = kind_params['DB_LINEAGE_NAME'].gsub(/text:/, "")
65
+ end
66
+ snapshots = Ec2EbsSnapshot.find_by_cloud_id(@servers.first.cloud_id).select { |n| n.nickname =~ /#{@lineage}.*$/ }
67
+ end
68
+
69
+ # Returns the timestamp of the latest snapshot for testing OPT_DB_RESTORE_TIMESTAMP_OVERRIDE
70
+ def find_snapshot_timestamp
71
+ last_snap = behavior(:find_snapshots).last
72
+ last_snap.tags.detect { |t| t["name"] =~ /timestamp=(\d+)$/ }
73
+ timestamp = $1
74
+ end
75
+
76
+ # creates a EBS stripe on the server
77
+ # * server<~Server> the server to create stripe on
78
+ def create_stripe_volume(server)
79
+ options = { "EBS_MOUNT_POINT" => "text:#{@mount_point}",
80
+ "EBS_STRIPE_COUNT" => "text:#{@stripe_count}",
81
+ "EBS_TOTAL_VOLUME_GROUP_SIZE" => "text:#{@volume_size}",
82
+ "EBS_LINEAGE" => "text:#{@lineage}" }
83
+ audit = server.run_executable(@scripts_to_run['create_stripe'], options)
84
+ audit.wait_for_completed
85
+ end
86
+
87
+ # * server<~Server> the server to restore to
88
+ def restore_from_backup(server,force)
89
+ options = { "EBS_MOUNT_POINT" => "text:#{@mount_point}",
90
+ "OPT_DB_FORCE_RESTORE" => "text:#{force}",
91
+ "EBS_LINEAGE" => "text:#{@lineage}" }
92
+ audit = server.run_executable(@scripts_to_run['restore'], options)
93
+ audit.wait_for_completed
94
+ end
95
+
96
+ # * server<~Server> the server to restore to
97
+ def restore_and_grow(server,new_size,force)
98
+ options = { "EBS_MOUNT_POINT" => "text:#{@mount_point}",
99
+ "EBS_TOTAL_VOLUME_GROUP_SIZE" => "text:#{new_size}",
100
+ "OPT_DB_FORCE_RESTORE" => "text:#{force}",
101
+ "EBS_LINEAGE" => "text:#{@lineage}" }
102
+ audit = server.run_executable(@scripts_to_run['grow_volume'], options)
103
+ audit.wait_for_completed
104
+ end
105
+
106
+ # Verify that the volume has special data on it.
107
+ def test_volume_data(server)
108
+ server.spot_check_command("test -f #{@mount_point}/data.txt")
109
+ end
110
+
111
+ # Verify that the volume is the expected size
112
+ def test_volume_size(server,expected_size)
113
+ puts "Testing with: #{@mount_point} #{expected_size}"
114
+ puts "THIS DOES NOT WORK - cause of rounding errors during volume size determination, FS overhead and df's output"
115
+ puts "Need to query the volumes attached to the server and verify that they #{expected_size}/#{@stripe_count}"
116
+ puts "Check that the server's volumes are #{expected_size}"
117
+ # server.spot_check_command("df -kh | awk -F\" \" -v -v size=#{expected_size}G '/#{@mount_point}/ {exit $2!=size}'")
118
+ end
119
+
120
+ # Writes data to the EBS volume so snapshot restores can be verified
121
+ # Not sure what to write...... Maybe pass a string to write to a file??..
122
+ def populate_volume(server)
123
+ server.spot_check_command(" echo \"blah blah blah\" > #{@mount_point}/data.txt")
124
+ end
125
+
126
+ # * server<~Server> the server to terminate
127
+ def terminate_server(server)
128
+ options = { "EBS_MOUNT_POINT" => "text:#{@mount_point}",
129
+ "EBS_TERMINATE_SAFETY" => "text:off" }
130
+ audit = server.run_executable(@scripts_to_run['terminate'], options)
131
+ audit.wait_for_completed
132
+ end
133
+
134
+ # Use the termination script to stop all the servers (this cleans up the volumes)
135
+ def stop_all
136
+ @servers.each do |s|
137
+ terminate_server(s) if s.state == 'operational' || s.state == 'stranded'
138
+ end
139
+ @servers.each { |s| s.wait_for_state("stopped") }
140
+ # unset dns in our local cached copy..
141
+ @servers.each { |s| s.params['dns-name'] = nil }
142
+ end
143
+ def test_restore_grow
144
+ grow_to_size=100
145
+ behavior(:restore_and_grow, s_three, grow_to_size, false)
146
+ behavior(:test_volume_data, s_three)
147
+ behavior(:test_volume_size, s_three, grow_to_size)
148
+ end
149
+
150
+ def test_restore
151
+ behavior(:restore_from_backup, s_two, false)
152
+ behavior(:test_volume_data, s_two)
153
+ end
154
+
155
+ def create_backup
156
+ behavior(:run_script, "backup", s_one)
157
+ behavior(:wait_for_snapshots)
158
+ end
159
+
160
+ end
161
+ end