openshift-origin-controller 1.3.2

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 (180) hide show
  1. data/COPYRIGHT +1 -0
  2. data/Gemfile +4 -0
  3. data/LICENSE +12 -0
  4. data/README.md +3 -0
  5. data/Rakefile +9 -0
  6. data/app/controllers/app_events_controller.rb +115 -0
  7. data/app/controllers/application_templates_controller.rb +19 -0
  8. data/app/controllers/applications_controller.rb +214 -0
  9. data/app/controllers/base_controller.rb +367 -0
  10. data/app/controllers/cartridges_controller.rb +48 -0
  11. data/app/controllers/descriptors_controller.rb +23 -0
  12. data/app/controllers/dns_resolvable_controller.rb +35 -0
  13. data/app/controllers/domains_controller.rb +156 -0
  14. data/app/controllers/emb_cart_controller.rb +276 -0
  15. data/app/controllers/emb_cart_events_controller.rb +52 -0
  16. data/app/controllers/environment_controller.rb +11 -0
  17. data/app/controllers/estimates_controller.rb +71 -0
  18. data/app/controllers/gear_groups_controller.rb +53 -0
  19. data/app/controllers/gears_controller.rb +70 -0
  20. data/app/controllers/keys_controller.rb +96 -0
  21. data/app/controllers/legacy_broker_controller.rb +510 -0
  22. data/app/controllers/quickstarts_controller.rb +29 -0
  23. data/app/controllers/user_controller.rb +38 -0
  24. data/app/helpers/cartridge_helper.rb +25 -0
  25. data/app/helpers/legacy_broker_helper.rb +21 -0
  26. data/app/helpers/user_action_logger.rb +38 -0
  27. data/app/models/application.rb +1718 -0
  28. data/app/models/application_template.rb +27 -0
  29. data/app/models/cartridge_cache.rb +51 -0
  30. data/app/models/cloud_user.rb +334 -0
  31. data/app/models/component_instance.rb +228 -0
  32. data/app/models/connection_endpoint.rb +10 -0
  33. data/app/models/district.rb +210 -0
  34. data/app/models/domain.rb +234 -0
  35. data/app/models/gear.rb +376 -0
  36. data/app/models/group_instance.rb +306 -0
  37. data/app/models/key.rb +20 -0
  38. data/app/models/legacy_reply.rb +15 -0
  39. data/app/models/legacy_request.rb +126 -0
  40. data/app/models/link.rb +11 -0
  41. data/app/models/message.rb +10 -0
  42. data/app/models/name_server_cache.rb +46 -0
  43. data/app/models/optional_param.rb +12 -0
  44. data/app/models/param.rb +13 -0
  45. data/app/models/remote_job.rb +57 -0
  46. data/app/models/rest_application.rb +126 -0
  47. data/app/models/rest_application10.rb +106 -0
  48. data/app/models/rest_application12.rb +124 -0
  49. data/app/models/rest_application_estimate.rb +12 -0
  50. data/app/models/rest_application_template.rb +20 -0
  51. data/app/models/rest_cartridge10.rb +41 -0
  52. data/app/models/rest_cartridge11.rb +151 -0
  53. data/app/models/rest_domain.rb +43 -0
  54. data/app/models/rest_domain10.rb +42 -0
  55. data/app/models/rest_estimates.rb +16 -0
  56. data/app/models/rest_gear.rb +14 -0
  57. data/app/models/rest_gear_group.rb +26 -0
  58. data/app/models/rest_key.rb +24 -0
  59. data/app/models/rest_reply.rb +31 -0
  60. data/app/models/rest_user.rb +43 -0
  61. data/app/models/result_io.rb +67 -0
  62. data/app/models/usage_record.rb +37 -0
  63. data/app/models/validators/app_validator.rb +30 -0
  64. data/app/models/validators/key_validator.rb +30 -0
  65. data/app/models/validators/namespace_validator.rb +18 -0
  66. data/config/routes.rb +36 -0
  67. data/lib/controller_engine.rb +7 -0
  68. data/lib/openshift-origin-controller.rb +14 -0
  69. data/lib/openshift/application_container_proxy.rb +241 -0
  70. data/lib/openshift/auth_service.rb +101 -0
  71. data/lib/openshift/data_store.rb +33 -0
  72. data/lib/openshift/dns_service.rb +41 -0
  73. data/lib/openshift/mongo_data_store.rb +671 -0
  74. data/openshift-origin-controller.gemspec +42 -0
  75. data/rubygem-openshift-origin-controller.spec +274 -0
  76. data/test/cucumber/application-estimate.feature +25 -0
  77. data/test/cucumber/cartridge-10gen-mms-agent.feature +28 -0
  78. data/test/cucumber/cartridge-cron.feature +32 -0
  79. data/test/cucumber/cartridge-haproxy.feature +31 -0
  80. data/test/cucumber/cartridge-jenkins-build.feature +12 -0
  81. data/test/cucumber/cartridge-jenkins-client.feature +10 -0
  82. data/test/cucumber/cartridge-lifecycle-diy.feature +21 -0
  83. data/test/cucumber/cartridge-lifecycle-jbossas.feature +61 -0
  84. data/test/cucumber/cartridge-lifecycle-jbosseap.feature +61 -0
  85. data/test/cucumber/cartridge-lifecycle-jbossews10.feature +61 -0
  86. data/test/cucumber/cartridge-lifecycle-jenkins.feature +41 -0
  87. data/test/cucumber/cartridge-lifecycle-nodejs.feature +59 -0
  88. data/test/cucumber/cartridge-lifecycle-perl.feature +40 -0
  89. data/test/cucumber/cartridge-lifecycle-php.feature +106 -0
  90. data/test/cucumber/cartridge-lifecycle-python.feature +40 -0
  91. data/test/cucumber/cartridge-lifecycle-ruby18.feature +49 -0
  92. data/test/cucumber/cartridge-lifecycle-ruby19.feature +41 -0
  93. data/test/cucumber/cartridge-mongodb.feature +31 -0
  94. data/test/cucumber/cartridge-mysql.feature +30 -0
  95. data/test/cucumber/cartridge-php.feature +14 -0
  96. data/test/cucumber/cartridge-phpmyadmin.feature +32 -0
  97. data/test/cucumber/cartridge-postgresql.feature +32 -0
  98. data/test/cucumber/cartridge-runtime-extended-db.feature +64 -0
  99. data/test/cucumber/cartridge-runtime-extended-jboss.feature +24 -0
  100. data/test/cucumber/cartridge-runtime-extended-nodejs.feature +21 -0
  101. data/test/cucumber/cartridge-runtime-extended-perl.feature +18 -0
  102. data/test/cucumber/cartridge-runtime-extended-php.feature +19 -0
  103. data/test/cucumber/cartridge-runtime-extended-python.feature +18 -0
  104. data/test/cucumber/cartridge-runtime-extended-ruby.feature +22 -0
  105. data/test/cucumber/cartridge-runtime-standard-diy.feature +6 -0
  106. data/test/cucumber/cartridge-runtime-standard-jbossas.feature +7 -0
  107. data/test/cucumber/cartridge-runtime-standard-jbosseap.feature +7 -0
  108. data/test/cucumber/cartridge-runtime-standard-jbossews10.feature +7 -0
  109. data/test/cucumber/cartridge-runtime-standard-jenkins.feature +8 -0
  110. data/test/cucumber/cartridge-runtime-standard-nodejs.feature +7 -0
  111. data/test/cucumber/cartridge-runtime-standard-perl.feature +6 -0
  112. data/test/cucumber/cartridge-runtime-standard-php.feature +6 -0
  113. data/test/cucumber/cartridge-runtime-standard-python.feature +6 -0
  114. data/test/cucumber/cartridge-runtime-standard-ruby.feature +19 -0
  115. data/test/cucumber/cartridge-switchyard.feature +36 -0
  116. data/test/cucumber/descriptor.feature +40 -0
  117. data/test/cucumber/embedded.feature +44 -0
  118. data/test/cucumber/idler.feature +75 -0
  119. data/test/cucumber/misc/descriptor/manifest.yml +22 -0
  120. data/test/cucumber/misc/php/db_test.php +21 -0
  121. data/test/cucumber/openshift-node.feature +21 -0
  122. data/test/cucumber/rest-application-templates.feature +31 -0
  123. data/test/cucumber/rest-applications.feature +431 -0
  124. data/test/cucumber/rest-cartridge-types.feature +16 -0
  125. data/test/cucumber/rest-domains.feature +276 -0
  126. data/test/cucumber/rest-gears.feature +38 -0
  127. data/test/cucumber/rest-keys.feature +247 -0
  128. data/test/cucumber/rest-quickstarts.feature +27 -0
  129. data/test/cucumber/rest-workflow.feature +64 -0
  130. data/test/cucumber/step_definitions/api_steps.rb +369 -0
  131. data/test/cucumber/step_definitions/application-estimate-steps.rb +51 -0
  132. data/test/cucumber/step_definitions/application_steps.rb +215 -0
  133. data/test/cucumber/step_definitions/cartridge-10gen-mms-agent_steps.rb +11 -0
  134. data/test/cucumber/step_definitions/cartridge-cron_steps.rb +51 -0
  135. data/test/cucumber/step_definitions/cartridge-haproxy_steps.rb +30 -0
  136. data/test/cucumber/step_definitions/cartridge-jenkins_steps.rb +93 -0
  137. data/test/cucumber/step_definitions/cartridge-lifecycle-nodejs_steps.rb +30 -0
  138. data/test/cucumber/step_definitions/cartridge-mongodb_steps.rb +60 -0
  139. data/test/cucumber/step_definitions/cartridge-mysql_steps.rb +56 -0
  140. data/test/cucumber/step_definitions/cartridge-php_steps.rb +72 -0
  141. data/test/cucumber/step_definitions/cartridge-postgresql_steps.rb +59 -0
  142. data/test/cucumber/step_definitions/cartridge-switchyard_steps.rb +29 -0
  143. data/test/cucumber/step_definitions/client_steps.rb +12 -0
  144. data/test/cucumber/step_definitions/descriptor_step.rb +32 -0
  145. data/test/cucumber/step_definitions/idler_steps.rb +37 -0
  146. data/test/cucumber/step_definitions/node_steps.rb +203 -0
  147. data/test/cucumber/step_definitions/runtime_steps.rb +547 -0
  148. data/test/cucumber/step_definitions/runtime_url_steps.rb +46 -0
  149. data/test/cucumber/step_definitions/trap-user-extended_steps.rb +14 -0
  150. data/test/cucumber/step_definitions/trap-user_steps.rb +58 -0
  151. data/test/cucumber/support/00_setup_helper.rb +106 -0
  152. data/test/cucumber/support/app_helper.rb +243 -0
  153. data/test/cucumber/support/assertions.rb +52 -0
  154. data/test/cucumber/support/command_helper.rb +453 -0
  155. data/test/cucumber/support/dns_helper.rb +54 -0
  156. data/test/cucumber/support/env.rb +5 -0
  157. data/test/cucumber/support/process_helper.rb +44 -0
  158. data/test/cucumber/support/runtime_support.rb +440 -0
  159. data/test/cucumber/support/unused.rb +27 -0
  160. data/test/cucumber/support/user_helper.rb +37 -0
  161. data/test/cucumber/trap-user-extended.feature +53 -0
  162. data/test/cucumber/trap-user.feature +34 -0
  163. data/test/ddns/1.168.192-rev.db.init +13 -0
  164. data/test/ddns/HOWTO.txt +207 -0
  165. data/test/ddns/Kexample.com.+157+06142.key +1 -0
  166. data/test/ddns/Kexample.com.+157+06142.private +7 -0
  167. data/test/ddns/authconfig.rb +14 -0
  168. data/test/ddns/example.com.db.init +23 -0
  169. data/test/ddns/example.com.key +4 -0
  170. data/test/ddns/named.ca +52 -0
  171. data/test/ddns/named.conf +48 -0
  172. data/test/ddns/named.empty +10 -0
  173. data/test/ddns/named.localhost +10 -0
  174. data/test/ddns/named.loopback +11 -0
  175. data/test/ddns/named.rfc1912.zones +42 -0
  176. data/test/ddns/named.root.key +5 -0
  177. data/test/ddns/named_service.rb +127 -0
  178. data/test/unit/bind_dns_service_test.rb +167 -0
  179. data/test/unit/broker_auth_test.rb +28 -0
  180. metadata +545 -0
@@ -0,0 +1,52 @@
1
+ require 'benchmark'
2
+ require 'test/unit/assertions'
3
+
4
+ ## Run code block and log performance results
5
+ def record_measure_elapsed(label)
6
+ elapsed = Benchmark.realtime do
7
+ yield
8
+ end
9
+
10
+ mins, secs = elapsed.abs.divmod(60)
11
+ $logger.debug("#{label}: #{mins}m #{secs.to_i}s")
12
+ end
13
+
14
+ ## Run code block and log performance results
15
+ def record_measure(label)
16
+ $logger.debug(
17
+ tms = Benchmark.measure(label) do
18
+ yield
19
+ end.format("%n: %10.6rreal %10.6u user %10.6y sys")
20
+ )
21
+ end
22
+
23
+ ## Provide far more meaninful messages than 'assert File.exists?(...)'
24
+
25
+ def assert_directory_exists(filename, msg = nil)
26
+ full_message = build_message(msg, "Directory ? should have been found.", filename)
27
+ assert_block(full_message) do
28
+ File.directory?(filename)
29
+ end
30
+ end
31
+
32
+ def assert_directory_not_exists(filename, msg = nil)
33
+ full_message = build_message(msg, "Directory ? should not have been found.", filename)
34
+ assert_block(full_message) do
35
+ ! File.directory?(filename)
36
+ end
37
+ end
38
+
39
+ def assert_file_exists(filename, msg = nil)
40
+ full_message = build_message(msg, "File ? should have been found.", filename)
41
+ assert_block(full_message) do
42
+ File.exists?(filename)
43
+ end
44
+ end
45
+
46
+ def assert_file_not_exists(filename, msg = nil)
47
+ full_message = build_message(msg, "File ? should not have been found.", filename)
48
+ assert_block(full_message) do
49
+ ! File.exists?(filename)
50
+ end
51
+ end
52
+
@@ -0,0 +1,453 @@
1
+ require 'timeout'
2
+ require 'fileutils'
3
+ require 'open3'
4
+ require 'open4'
5
+ require 'benchmark'
6
+
7
+ module CommandHelper
8
+ def run_stdout(cmd)
9
+ $logger.info("Running: #{cmd}")
10
+
11
+ exit_code = -1
12
+ output = nil
13
+
14
+ # Don't let a command run more than 5 minutes
15
+ Timeout::timeout(500) do
16
+ output = `#{cmd} 2>&1`
17
+ exit_code = $?.exitstatus
18
+ end
19
+
20
+ $logger.error("(#{$$}): Execution failed #{cmd} with exit_code: #{exit_code.to_s} and output:\n #{output}") if exit_code != 0
21
+ exit_code.should == 0
22
+ return output
23
+ end
24
+
25
+ def run(cmd, outbuf=[], retries=0)
26
+ $logger.info("Running: #{cmd}")
27
+
28
+ exit_code = -1
29
+ output = nil
30
+
31
+ # Don't let a command run more than 5 minutes
32
+ Timeout::timeout(500) do
33
+ output = `#{cmd} 2>&1`
34
+ exit_code = $?.exitstatus
35
+ end
36
+
37
+ $logger.debug("Output:\n#{output}")
38
+
39
+ if exit_code != 0
40
+ $logger.error("(#{$$}): Execution failed #{cmd} with exit_code: #{exit_code.to_s}")
41
+ if retries < 3 && exit_code == 140 && cmd.start_with?("/usr/bin/rhc-") #No nodes available... ugh
42
+ $logger.debug("Restarting #{$gear_update_plugin_service} and retrying")
43
+ $logger.debug `service #{$gear_update_plugin_service} restart`
44
+ sleep 5
45
+ return run(cmd, outbuf, retries+1)
46
+ end
47
+ end
48
+
49
+ # append the buffers if an array container is provided
50
+ if outbuf
51
+ outbuf << output
52
+ end
53
+
54
+ return exit_code
55
+ end
56
+
57
+ # run a command in an alternate SELinux context, if provided
58
+ def runcon(cmd, user=nil, role=nil, type=nil, outbuf=nil, time_limit_sec=600)
59
+ if user.nil? and role.nil? and type.nil?
60
+ exit_code = run cmd, outbuf
61
+ return exit_code
62
+ end
63
+
64
+ prefix = 'runcon'
65
+ prefix += (' -u ' + user) if user
66
+ prefix += (' -r ' + role) if role
67
+ prefix += (' -t ' + type) if type
68
+ fullcmd = prefix + " " + cmd
69
+
70
+ time_start = Time.now
71
+ output = `#{fullcmd} 2>&1`
72
+ exit_code = $?.exitstatus
73
+ execute_time = Time.now - time_start
74
+ raise "Time limit reached. Limit: #{time_limit_sec}s Actual: #{execute_time}s" if execute_time > time_limit_sec
75
+
76
+ $logger.debug("Command run: #{fullcmd}")
77
+ $logger.debug("Output:\n#{output}")
78
+ $logger.debug("Exit Code: #{exit_code}")
79
+ $logger.debug("Time limit: #{time_limit_sec}s Actual: #{execute_time}s") if time_limit_sec
80
+ # append the buffers if an array container is provided
81
+ if outbuf
82
+ outbuf << output
83
+ end
84
+
85
+ $logger.error("(#{$$}): Execution failed #{cmd} with exit_code: #{exit_code.to_s}") if exit_code != 0
86
+
87
+ return exit_code
88
+ end
89
+
90
+ def log_event(str)
91
+ $perfmon_logger.info "#{Thread.current} #{str}"
92
+ end
93
+
94
+ def rhc_sshkey_upload(app, name ='default', key=File.join(ENV["HOME"], '.ssh', 'id_rsa.pub'))
95
+ rhc_do('rhc_sshkey_upload') do
96
+ cmd = "#{$rhc_script} sshkey add -l #{app.login} -p #{app.password} #{name} #{key} --confirm"
97
+ exit_code = 0
98
+
99
+ time = Benchmark.realtime do
100
+ exit_code = run(cmd)
101
+ end
102
+
103
+ log_event "#{time} SSHKEY_ADD #{name} #{key}"
104
+ return exit_code == 0
105
+ end
106
+ end
107
+
108
+ def rhc_create_domain(app)
109
+ rhc_do('rhc_create_domain') do
110
+
111
+ exit_code = 0
112
+ time = Benchmark.realtime do
113
+ exit_code = run("#{$rhc_script} domain create -l #{app.login} -p #{app.password} #{app.namespace} -d")
114
+ end
115
+ log_event "#{time} CREATE_DOMAIN #{app.namespace} #{app.login}"
116
+
117
+ app.create_domain_code = exit_code
118
+ return exit_code == 0
119
+ end
120
+ end
121
+
122
+ def rhc_update_namespace(app)
123
+ rhc_do('rhc_update_namespace') do
124
+ old_namespace = app.namespace
125
+ if old_namespace.end_with?('new')
126
+ app.namespace = new_namespace = old_namespace[0..-4]
127
+ else
128
+ app.namespace = new_namespace = old_namespace + "new"
129
+ end
130
+ old_hostname = app.hostname
131
+ app.hostname = "#{app.name}-#{new_namespace}.#{$domain}"
132
+ old_repo = app.repo
133
+ app.repo = "#{$temp}/#{new_namespace}_#{app.name}_repo"
134
+ FileUtils.mv old_repo, app.repo
135
+
136
+ if run("grep '#{old_hostname}' #{app.repo}/.git/config") == 0
137
+ run("sed -i 's,#{old_hostname},#{app.hostname},g' #{app.repo}/.git/config")
138
+ end
139
+
140
+ if run("grep '#{app.name}-#{old_namespace}.#{$domain}' /etc/hosts") == 0
141
+ run("sed -i 's,#{app.name}-#{old_namespace}.#{$domain},#{app.name}-#{new_namespace}.#{$domain},g' /etc/hosts")
142
+ end
143
+ old_file = app.file
144
+ app.file = "#{$temp}/#{new_namespace}.json"
145
+ FileUtils.mv old_file, app.file
146
+ time = Benchmark.realtime do
147
+ run("#{$rhc_script} domain update #{old_namespace} #{new_namespace} -l #{app.login} -p #{app.password} -d").should == 0
148
+ end
149
+ log_event "#{time} UPDATE_DOMAIN #{new_namespace} #{app.login}"
150
+ app.persist
151
+ end
152
+ end
153
+
154
+ def rhc_snapshot(app)
155
+ rhc_do('rhc_snapshot') do
156
+ app.snapshot="/tmp/#{app.name}-#{app.namespace}.tar.gz"
157
+ FileUtils.rm_rf app.snapshot
158
+ time = Benchmark.realtime do
159
+ run("#{$rhc_script} snapshot save -l #{app.login} -p #{app.password} --app #{app.name} -f '#{app.snapshot}' -d").should == 0
160
+ end
161
+ log_event "#{time} CREATE_SNAPSHOT #{app.name} #{app.login}"
162
+ app.persist
163
+ end
164
+ output = `ls -l #{app.snapshot}`
165
+ $logger.info("snapshot: #{output}")
166
+ end
167
+
168
+ def rhc_restore(app)
169
+ output = `ls -l #{app.snapshot}`
170
+ $logger.info("restore: #{output}")
171
+
172
+ rhc_do('rhc_restore') do
173
+ time = Benchmark.realtime do
174
+ run("#{$rhc_script} snapshot restore -l #{app.login} -p #{app.password} --app #{app.name} -f '#{app.snapshot}' -d").should == 0
175
+ end
176
+ log_event "#{time} RESTORE_SNAPSHOT #{app.name} #{app.login}"
177
+ end
178
+ end
179
+
180
+ def rhc_tidy(app)
181
+ rhc_do('rhc_tidy') do
182
+ time = Benchmark.realtime do
183
+ run("#{$rhc_script} app tidy -l #{app.login} -a #{app.name} -p #{app.password} -d").should == 0
184
+ end
185
+ log_event "#{time} TIDY_APP #{app.name} #{app.login}"
186
+ end
187
+ end
188
+
189
+ def rhc_create_app(app, use_hosts=true, misc_opts='')
190
+ rhc_sshkey_upload app
191
+
192
+ rhc_do('rhc_create_app') do
193
+ cmd = "#{$rhc_script} app create -l #{app.login} -a #{app.name} -r #{app.repo} -t #{app.type} -p #{app.password} #{misc_opts} -d"
194
+
195
+ # Short circuit DNS to speed up the tests by adding a host entry and skipping the DNS validation
196
+ if use_hosts
197
+ run("echo '127.0.0.1 #{app.name}-#{app.namespace}.#{$domain} # Added by cucumber' >> /etc/hosts")
198
+ run("mkdir -m 700 -p ~/.ssh")
199
+ run("test -f ~/.ssh/known_hosts && awk 1 ~/.ssh/known_hosts > ~/.ssh/known_hosts- && mv -f ~/.ssh/known_hosts- ~/.ssh/known_hosts")
200
+ run("ssh-keyscan '#{app.name}-#{app.namespace}.#{$domain}' >> ~/.ssh/known_hosts")
201
+ run("chmod 644 ~/.ssh/known_hosts")
202
+ # cmd << " --no-dns"
203
+ end
204
+
205
+ output_buffer = []
206
+ exit_code = 0
207
+ time = Benchmark.realtime do
208
+ exit_code = run(cmd, output_buffer)
209
+ end
210
+ log_event "#{time} CREATE_APP #{app.name} #{app.type} #{app.login}"
211
+
212
+ # Update the application uid from the command output
213
+ begin
214
+ app.update_uid(output_buffer[0])
215
+ rescue NoMethodError
216
+ $logger.debug("Creating the app failed. #{cmd} returned #{output_buffer[0]}")
217
+ raise
218
+ end
219
+
220
+ # Update the application creation code
221
+ app.create_app_code = exit_code
222
+
223
+ # Persist the app data to filesystem
224
+ app.persist
225
+
226
+ return app
227
+ end
228
+ end
229
+
230
+ def rhc_embed_add(app, type)
231
+ rhc_do('rhc_embed_add') do
232
+ result = nil
233
+ time = Benchmark.realtime do
234
+ result = run_stdout("#{$rhc_script} cartridge add -l #{app.login} -a #{app.name} -p #{app.password} -c #{type} -d")
235
+ end
236
+ $logger.info { "Embed #{type} into #{app.inspect}: OUTPUT\n#{result}" }
237
+ log_event "#{time} ADD_EMBED_CART #{app.name} #{type} #{app.login}"
238
+ if type.start_with?('mysql-')
239
+ # Recent versions of rhc now return a connection URL in this format:
240
+ #
241
+ # mysql://$OPENSHIFT_MYSQL_DB_HOST:$OPENSHIFT_MYSQL_DB_PORT/
242
+ #
243
+ # So, we have to extract the env vars and source them from the gear
244
+ # directory to get the actual values to attach to the app.
245
+
246
+ # Source the env var values from the gear directory
247
+ host_val = `source /var/lib/openshift/#{app.uid}/.env/OPENSHIFT_MYSQL_DB_HOST;echo $OPENSHIFT_MYSQL_DB_HOST`.chomp!
248
+ port_val = `source /var/lib/openshift/#{app.uid}/.env/OPENSHIFT_MYSQL_DB_PORT;echo $OPENSHIFT_MYSQL_DB_PORT`.chomp!
249
+
250
+ # Assign the hostname ourselves, in host:port format
251
+ app.mysql_hostname = "#{host_val}:#{port_val}"
252
+ app.mysql_user = /Username\s*=\s*(\S+)/.match(result)[1]
253
+ app.mysql_password = /Password\s*=\s*(\S+)/.match(result)[1]
254
+ app.mysql_database = /Database Name\s*=\s*(\S+)/.match(result)[1]
255
+
256
+ app.mysql_hostname.should_not be_nil
257
+ app.mysql_user.should_not be_nil
258
+ app.mysql_password.should_not be_nil
259
+ app.mysql_database.should_not be_nil
260
+ end
261
+
262
+ app.embed.push(type)
263
+ app.persist
264
+ return app
265
+ end
266
+ end
267
+
268
+ def rhc_embed_remove(app, type)
269
+ rhc_do('rhc_embed_remove') do
270
+ # puts app.name
271
+ time = Benchmark.realtime do
272
+ run("#{$rhc_script} cartridge remove -l #{app.login} -a #{app.name} -p #{app.password} -c #{type} --confirm -d").should == 0
273
+ end
274
+ log_event "#{time} REMOVE_EMBED_CART #{app.name} #{type} #{app.login}"
275
+ app.mysql_hostname = nil
276
+ app.mysql_user = nil
277
+ app.mysql_password = nil
278
+ app.mysql_database = nil
279
+ app.embed.delete(type)
280
+ app.persist
281
+ return app
282
+ end
283
+ end
284
+
285
+ def rhc_ctl_stop(app)
286
+ rhc_do('rhc_ctl_stop') do
287
+ time = Benchmark.realtime do
288
+ run("#{$rhc_script} app stop -l #{app.login} -p #{app.password} #{app.name} -d").should == 0
289
+ end
290
+ log_event "#{time} STOP_APP #{app.name} #{app.login}"
291
+ time = Benchmark.realtime do
292
+ run("#{$rhc_script} app show -l #{app.login} -p #{app.password} #{app.name} --state | grep '#{app.get_stop_string}'").should == 0
293
+ end
294
+ log_event "#{time} STATUS_APP #{app.name} #{app.login}"
295
+ end
296
+ end
297
+
298
+ def rhc_add_alias(app)
299
+ rhc_do('rhc_add_alias') do
300
+ time = Benchmark.realtime do
301
+ run("#{$rhc_script} alias add -l #{app.login} -p #{app.password} #{app.name} '#{app.name}-#{app.namespace}.#{$alias_domain}' -d").should == 0
302
+ end
303
+ log_event "#{time} ADD_ALIAS #{app.name} #{app.login}"
304
+ end
305
+ end
306
+
307
+ def rhc_remove_alias(app)
308
+ rhc_do('rhc_remove_alias') do
309
+ time = Benchmark.realtime do
310
+ run("#{$rhc_script} alias remove -l #{app.login} -p #{app.password} #{app.name} '#{app.name}-#{app.namespace}.#{$alias_domain}' -d").should == 0
311
+ end
312
+ log_event "#{time} REMOVE_ALIAS #{app.name} #{app.login}"
313
+ end
314
+ end
315
+
316
+ def rhc_ctl_start(app)
317
+ rhc_do('rhc_ctl_start') do
318
+ time = Benchmark.realtime do
319
+ run("#{$rhc_script} app start -l #{app.login} -p #{app.password} #{app.name} -d").should == 0
320
+ end
321
+ log_event "#{time} START_APP #{app.name} #{app.login}"
322
+ time = Benchmark.realtime do
323
+ run("#{$rhc_script} app show -l #{app.login} -p #{app.password} #{app.name} --state | grep '#{app.get_stop_string}'").should == 1
324
+ end
325
+ log_event "#{time} STATUS_APP #{app.name} #{app.login}"
326
+ end
327
+ end
328
+
329
+ def rhc_ctl_restart(app)
330
+ rhc_do('rhc_ctl_restart') do
331
+ time = Benchmark.realtime do
332
+ run("#{$rhc_script} app restart -l #{app.login} -p #{app.password} #{app.name} -d").should == 0
333
+ end
334
+ log_event "#{time} RESTART_APP #{app.name} #{app.login}"
335
+ time = Benchmark.realtime do
336
+ run("#{$rhc_script} app show -l #{app.login} -p #{app.password} #{app.name} --state | grep '#{app.get_stop_string}'").should == 1
337
+ end
338
+ log_event "#{time} STATUS_APP #{app.name} #{app.login}"
339
+ end
340
+ end
341
+
342
+ def rhc_ctl_destroy(app, use_hosts=true)
343
+ rhc_do('rhc_ctl_destroy') do
344
+ time = Benchmark.realtime do
345
+ run("#{$rhc_script} app delete -l #{app.login} -p #{app.password} #{app.name} --confirm -d").should == 0
346
+ end
347
+ log_event "#{time} DESTROY_APP #{app.name} #{app.login}"
348
+ time = Benchmark.realtime do
349
+ run("#{$rhc_script} app show -l #{app.login} -p #{app.password} #{app.name} --state | grep 'does not exist'").should == 0
350
+ end
351
+ log_event "#{time} STATUS_APP #{app.name} #{app.login}"
352
+ run("sed -i '/#{app.name}-#{app.namespace}.#{$domain}/d' /etc/hosts") if use_hosts
353
+ FileUtils.rm_rf app.repo
354
+ FileUtils.rm_rf app.file
355
+ end
356
+ end
357
+
358
+ def rhc_setup
359
+ run('mkdir -p ~/.openshift')
360
+ run('touch ~/.openshift/express.conf')
361
+ end
362
+
363
+ def rhc_do(method, retries=2)
364
+ rhc_setup
365
+ i = 0
366
+ while true
367
+ begin
368
+ yield
369
+ break
370
+ rescue Exception => e
371
+ raise if i >= retries
372
+ $logger.debug "Retrying #{method} after exception caught: #{e.message}"
373
+ i += 1
374
+ end
375
+ end
376
+ end
377
+
378
+ #
379
+ # useful methods to avoid duplicating effort
380
+ #
381
+
382
+ #
383
+ # Count the number of processes owned by account with cmd_name
384
+ #
385
+ def num_procs acct_name, cmd_name, label=nil
386
+ ps_pattern = /^\s*(\d+)\s+(\S+)\s+(.*)/
387
+ command = "ps --no-headers -o pid,comm,args -u #{acct_name}"
388
+ $logger.debug("num_procs: executing #{command}")
389
+
390
+ stdin, stdout, stderr = Open3.popen3(command)
391
+
392
+ stdin.close
393
+ outstrings = stdout.readlines
394
+ errstrings = stderr.readlines
395
+
396
+ $logger.debug("looking for #{cmd_name}")
397
+ $logger.debug("ps output:\n" + outstrings.join(""))
398
+
399
+ proclist = outstrings.collect { |line|
400
+ match = line.match(ps_pattern)
401
+
402
+ next if match.nil?
403
+
404
+ pid = match[1]
405
+ command = match[2]
406
+ args = match[3]
407
+
408
+ command_matches = (command == cmd_name || command.end_with?("/#{cmd_name}"))
409
+ label_matches = (label.nil? || args.match(label))
410
+
411
+ if command_matches and label_matches
412
+ pid
413
+ end
414
+ }.compact
415
+
416
+ found = proclist ? proclist.size : 0
417
+
418
+ if (label)
419
+ $logger.debug("Found = #{found} instances of #{cmd_name} with args matching #{label}")
420
+ else
421
+ $logger.debug("Found = #{found} instances of #{cmd_name}")
422
+ end
423
+
424
+ found
425
+ end
426
+
427
+ #
428
+ # Count the number of processes owned by account that match the regex
429
+ #
430
+ def num_procs_like acct_name, regex
431
+ command = "ps --no-headers -f -u #{acct_name}"
432
+ $logger.debug("num_procs: executing #{command}")
433
+
434
+ stdin, stdout, stderr = Open3.popen3(command)
435
+
436
+ stdin.close
437
+
438
+ outstrings = stdout.readlines
439
+ errstrings = stderr.readlines
440
+ $logger.debug("looking for #{regex}")
441
+ $logger.debug("ps output:\n" + outstrings.join(""))
442
+
443
+ proclist = outstrings.collect { |line|
444
+ line.match(regex)
445
+ }.compact!
446
+
447
+ found = proclist ? proclist.size : 0
448
+ $logger.debug("Found = #{found} instances of #{regex}")
449
+ found
450
+ end
451
+ end
452
+
453
+ World(CommandHelper)