rhc 0.98.16 → 1.0.4

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 (94) hide show
  1. data/bin/rhc +7 -49
  2. data/bin/rhc-app +14 -3
  3. data/bin/rhc-chk +16 -16
  4. data/bin/rhc-create-app +2 -0
  5. data/bin/rhc-create-domain +1 -2
  6. data/bin/rhc-ctl-app +12 -3
  7. data/bin/rhc-ctl-domain +1 -2
  8. data/bin/rhc-domain +1 -2
  9. data/bin/rhc-domain-info +1 -2
  10. data/bin/rhc-port-forward +1 -2
  11. data/bin/rhc-snapshot +3 -0
  12. data/bin/rhc-sshkey +1 -2
  13. data/bin/rhc-tail-files +1 -1
  14. data/bin/rhc-user-info +1 -3
  15. data/features/application.feature +4 -1
  16. data/features/domain.feature +0 -4
  17. data/features/geared_application.feature +11 -0
  18. data/features/lib/rhc_helper/app.rb +16 -5
  19. data/features/lib/rhc_helper/cartridge.rb +25 -9
  20. data/features/lib/rhc_helper/commandify.rb +34 -7
  21. data/features/lib/rhc_helper/domain.rb +2 -2
  22. data/features/lib/rhc_helper/httpify.rb +24 -14
  23. data/features/lib/rhc_helper/persistable.rb +1 -1
  24. data/features/lib/rhc_helper/sshkey.rb +11 -7
  25. data/features/lib/rhc_helper.rb +5 -3
  26. data/features/multiple_cartridge.feature +1 -1
  27. data/features/scaled_application.feature +48 -0
  28. data/features/sshkey.feature +37 -31
  29. data/features/step_definitions/application_steps.rb +18 -7
  30. data/features/step_definitions/cartridge_steps.rb +29 -3
  31. data/features/step_definitions/domain_steps.rb +2 -2
  32. data/features/step_definitions/sshkey_steps.rb +34 -34
  33. data/features/support/assumptions.rb +21 -9
  34. data/features/support/before_hooks.rb +24 -6
  35. data/features/support/env.rb +45 -19
  36. data/lib/rhc/cartridge_helper.rb +27 -0
  37. data/lib/rhc/cli.rb +1 -1
  38. data/lib/rhc/command_runner.rb +31 -3
  39. data/lib/rhc/commands/alias.rb +38 -0
  40. data/lib/rhc/commands/app.rb +478 -0
  41. data/lib/rhc/commands/base.rb +42 -12
  42. data/lib/rhc/commands/cartridge.rb +189 -0
  43. data/lib/rhc/commands/domain.rb +11 -49
  44. data/lib/rhc/commands/port-forward.rb +0 -1
  45. data/lib/rhc/commands/setup.rb +2 -1
  46. data/lib/rhc/commands/snapshot.rb +118 -0
  47. data/lib/rhc/commands/sshkey.rb +24 -38
  48. data/lib/rhc/commands/tail.rb +24 -0
  49. data/lib/rhc/commands/threaddump.rb +16 -0
  50. data/lib/rhc/commands.rb +33 -7
  51. data/lib/rhc/config.rb +28 -12
  52. data/lib/rhc/context_helper.rb +19 -5
  53. data/lib/rhc/core_ext.rb +86 -0
  54. data/lib/rhc/exceptions.rb +44 -0
  55. data/lib/rhc/git_helper.rb +59 -0
  56. data/lib/rhc/helpers.rb +86 -5
  57. data/lib/rhc/output_helpers.rb +213 -0
  58. data/lib/rhc/rest/application.rb +134 -67
  59. data/lib/rhc/rest/base.rb +48 -0
  60. data/lib/rhc/rest/cartridge.rb +40 -44
  61. data/lib/rhc/rest/client.rb +127 -59
  62. data/lib/rhc/rest/domain.rb +29 -39
  63. data/lib/rhc/rest/gear_group.rb +10 -0
  64. data/lib/rhc/rest/key.rb +8 -23
  65. data/lib/rhc/rest/user.rb +8 -24
  66. data/lib/rhc/rest.rb +22 -11
  67. data/lib/rhc/ssh_key_helpers.rb +47 -0
  68. data/lib/rhc/usage_templates/help.erb +0 -1
  69. data/lib/rhc/version.rb +3 -3
  70. data/lib/rhc/wizard.rb +123 -225
  71. data/lib/rhc-common.rb +43 -62
  72. data/spec/rest_spec_helper.rb +159 -36
  73. data/spec/rhc/cli_spec.rb +29 -1
  74. data/spec/rhc/command_spec.rb +32 -35
  75. data/spec/rhc/commands/alias_spec.rb +123 -0
  76. data/spec/rhc/commands/app_spec.rb +414 -0
  77. data/spec/rhc/commands/cartridge_spec.rb +342 -0
  78. data/spec/rhc/commands/domain_spec.rb +8 -8
  79. data/spec/rhc/commands/setup_spec.rb +17 -6
  80. data/spec/rhc/commands/snapshot_spec.rb +140 -0
  81. data/spec/rhc/commands/sshkey_spec.rb +26 -4
  82. data/spec/rhc/commands/tail_spec.rb +34 -0
  83. data/spec/rhc/commands/threaddump_spec.rb +83 -0
  84. data/spec/rhc/config_spec.rb +39 -13
  85. data/spec/rhc/context_spec.rb +51 -0
  86. data/spec/rhc/helpers_spec.rb +52 -12
  87. data/spec/rhc/rest_application_spec.rb +16 -3
  88. data/spec/rhc/rest_client_spec.rb +144 -36
  89. data/spec/rhc/rest_spec.rb +1 -1
  90. data/spec/rhc/wizard_spec.rb +133 -232
  91. data/spec/spec_helper.rb +4 -3
  92. metadata +56 -31
  93. data/features/support/ssh.sh +0 -2
  94. data/spec/rhc/common_spec.rb +0 -49
@@ -6,6 +6,21 @@ module RHC
6
6
  commands.keys.find_all { |name| name if /^#{name}\b/.match arg_string }
7
7
  end
8
8
 
9
+ def options_parse_trace
10
+ if @args.include? "--trace"
11
+ @args.delete "--trace"
12
+ return true
13
+ end
14
+ false
15
+ end
16
+
17
+ def options_parse_version
18
+ if @args.include? "--version" or @args.include? "-v"
19
+ say version
20
+ exit 0
21
+ end
22
+ end
23
+
9
24
  # override so we can do our own error handling
10
25
  def run!
11
26
  trace = false
@@ -20,10 +35,23 @@ module RHC
20
35
  return
21
36
  end
22
37
  global_option('-v', '--version', 'Display version information') { say version; return }
23
- global_option('-t', '--trace', 'Display backtrace when an error occurs') { trace = true }
38
+ global_option('--timeout seconds', Integer, 'Set the timeout in seconds for network commands') do |value|
39
+ # FIXME: Refactor so we don't have to use a global var here
40
+ $rest_timeout = value
41
+ end
42
+
43
+ # remove these because we monkey patch Commands to process all options
44
+ # at once, avoiding conflicts between the global and command options
45
+ # code left here just in case someone compares this with the original
46
+ # commander code
47
+ #parse_global_options
48
+ #remove_global_options options, @args
49
+
50
+ # special case --trace because we need to use it in the runner
51
+ trace = options_parse_trace
24
52
 
25
- parse_global_options
26
- remove_global_options options, @args
53
+ # special case --version so it is processed before an invalid command
54
+ options_parse_version
27
55
 
28
56
  unless trace
29
57
  begin
@@ -0,0 +1,38 @@
1
+ require 'rhc/commands/base'
2
+ require 'rhc/config'
3
+ require 'rhc-common'
4
+ module RHC::Commands
5
+ class Alias < Base
6
+ summary "Add or remove a custom domain name for the application"
7
+ syntax "<command> <application> <alias> [--namespace namespace]"
8
+ default_action :help
9
+
10
+ summary "Add a custom domain name for the application"
11
+ syntax "<application> <alias> [--namespace namespace]"
12
+ argument :app, "Application name (required)", []
13
+ argument :app_alias, "Custom domain name for the application", []
14
+ option ["-n", "--namespace namespace"], "Namespace of your application", :context => :namespace_context, :required => true
15
+ alias_action :"app add-alias", :root_command => true, :deprecated => true
16
+ def add(app, app_alias)
17
+ rest_domain = rest_client.find_domain(options.namespace)
18
+ rest_app = rest_domain.find_application(app)
19
+ response = rest_app.add_alias(app_alias)
20
+ results { say response.messages.first } if response.messages
21
+ 0
22
+ end
23
+
24
+ summary "Remove a custom domain name for the application"
25
+ syntax "<application> <alias> [--namespace namespace]"
26
+ argument :app, "Application name (required)", []
27
+ argument :app_alias, "Custom domain name for the application", []
28
+ option ["-n", "--namespace namespace"], "Namespace of your application", :context => :namespace_context, :required => true
29
+ alias_action :"app remove-alias", :root_command => true, :deprecated => true
30
+ def remove(app, app_alias)
31
+ rest_domain = rest_client.find_domain(options.namespace)
32
+ rest_app = rest_domain.find_application(app)
33
+ response = rest_app.remove_alias(app_alias)
34
+ results { say response.messages.first } if response.messages
35
+ 0
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,478 @@
1
+ require 'rhc/commands/base'
2
+ require 'resolv'
3
+ require 'rhc/git_helper'
4
+ require 'rhc/cartridge_helper'
5
+
6
+ module RHC::Commands
7
+ class App < Base
8
+ summary "Commands for creating and managing applications"
9
+ description "Creates and controls an OpenShift application. To see the list of all applications use the rhc domain show command. Note that delete is not reversible and will stop your application and then remove the application and repo from the remote server. No local changes are made."
10
+ syntax "<action>"
11
+ default_action :help
12
+
13
+ summary "Create an application and adds it to a domain"
14
+ syntax "<name> <cartridge> [... <other cartridges>][--namespace namespace]"
15
+ option ["-n", "--namespace namespace"], "Namespace to add your application to", :context => :namespace_context, :required => true
16
+ option ["-g", "--gear-size size"], "The size of the gear for this app. Available gear sizes depend on the type of account you have."
17
+ option ["-s", "--scaling"], "Enable scaling for this application"
18
+ option ["-r", "--repo dir"], "Git Repo path (defaults to ./$app_name) (applicable to the create command)"
19
+ option ["--[no-]git"], "Only create remote space, don't pull it locally"
20
+ option ["--nogit"], "DEPRECATED! Only create remote space, don't pull it locally", :deprecated => {:key => :git, :value => false}
21
+ option ["--[no-]dns"], "Skip DNS check. Must be used in combination with --no-git"
22
+ option ["--enable-jenkins [server_name]"], "Indicates to create a Jenkins application (if not already available) and embed the Jenkins client into this application. The default name will be 'jenkins' if not specified. Note that --no-dns is ignored for the creation of the Jenkins application."
23
+ argument :name, "The name you wish to give your application", ["-a", "--app name"]
24
+ argument :cartridge, "The first cartridge added to the application. Usually a web framework", ["-t", "--type cartridge"]
25
+ argument :additional_cartridges, "A list of other cartridges such as databases you wish to add. Cartridges can also be added later using 'rhc cartridge add'", [], :arg_type => :list
26
+ def create(name, cartridge, additional_cartridges)
27
+ options.default \
28
+ :dns => true,
29
+ :git => true
30
+
31
+ warnings = []
32
+ header "Creating application '#{name}'"
33
+ paragraph do
34
+ table({"Namespace:" => options.namespace,
35
+ "Cartridge:" => cartridge,
36
+ "Gear Size:" => options.gear_size || "default",
37
+ "Scaling:" => options.scaling ? "yes" : "no",
38
+ }
39
+ ).each { |s| say " #{s}" }
40
+ end
41
+
42
+ raise RHC::DomainNotFoundException.new("No domains found. Please create a domain with 'rhc domain create <namespace>' before creating applications.") if rest_client.domains.empty?
43
+
44
+ rest_domain = rest_client.find_domain(options.namespace)
45
+
46
+ # check to make sure the right options are set for enabling jenkins
47
+ jenkins_rest_app = check_jenkins(name, rest_domain) if options.enable_jenkins
48
+
49
+ # create the main app
50
+ rest_app = create_app(name, cartridge, rest_domain,
51
+ options.gear_size, options.scaling)
52
+
53
+ # create a jenkins app if not available
54
+ # don't error out if there are issues, setup warnings instead
55
+ begin
56
+ jenkins_rest_app = setup_jenkins_app(rest_domain) if options.enable_jenkins and jenkins_rest_app.nil?
57
+ rescue Exception => e
58
+ add_issue("Jenkins failed to install - #{e}",
59
+ "Installing jenkins and jenkins-client",
60
+ "rhc app create jenkins",
61
+ "rhc cartridge add jenkins-client -a #{rest_app.name}")
62
+ end
63
+
64
+ if jenkins_rest_app
65
+ success, attempts, exit_code, exit_message = false, 1, 157, nil
66
+ while (!success && exit_code == 157 && attempts < MAX_RETRIES)
67
+ begin
68
+ setup_jenkins_client(rest_app)
69
+ success = true
70
+ rescue RHC::Rest::ServerErrorException => e
71
+ if (e.code == 157)
72
+ # error downloading Jenkins /jnlpJars/jenkins-cli.jar
73
+ attempts += 1
74
+ debug "Jenkins server could not be contacted, sleep and then retry: attempt #{attempts}\n #{e.message}"
75
+ sleep(10)
76
+ end
77
+ exit_code = e.code
78
+ exit_message = e.message
79
+ rescue Exception => e
80
+ # timeout and other exceptions
81
+ exit_code = 1
82
+ exit_message = e.message
83
+ end
84
+ end
85
+ add_issue("Jenkins client failed to install - #{exit_message}",
86
+ "Install the jenkins client",
87
+ "rhc cartridge add jenkins-client -a #{rest_app.name}") if !success
88
+ end
89
+
90
+ if options.dns
91
+ say "Your application's domain name is being propagated worldwide (this might take a minute)..."
92
+ unless dns_propagated? rest_app.host
93
+ add_issue("We were unable to lookup your hostname (#{rest_app.host}) in a reasonable amount of time and can not clone your application.",
94
+ "Clone your git repo",
95
+ "rhc app git-clone #{rest_app.name}")
96
+
97
+ output_issues(rest_app)
98
+ return 0
99
+ end
100
+
101
+ if options.git
102
+ begin
103
+ run_git_clone(rest_app)
104
+ rescue RHC::GitException => e
105
+ warn "#{e}"
106
+ unless RHC::Helpers.windows? and windows_nslookup_bug?(rest_app)
107
+ add_issue("We were unable to clone your application's git repo - #{e}",
108
+ "Clone your git repo",
109
+ "rhc app git-clone #{rest_app.name}")
110
+ end
111
+ end
112
+ end
113
+ end
114
+
115
+ display_app(rest_app, rest_app.cartridges, rest_app.scalable_carts.first)
116
+
117
+ if issues?
118
+ output_issues(rest_app)
119
+ else
120
+ results {
121
+ rest_app.messages.each { |msg| say msg }
122
+ jenkins_rest_app.messages.each { |msg| say msg } if options.enable_jenkins and jenkins_rest_app
123
+ }
124
+ end
125
+
126
+ 0
127
+ end
128
+
129
+ summary "Clone and configure an application's repository locally"
130
+ description "This is a convenience wrapper for 'git clone' with the added",
131
+ "benefit of adding configuration data such as the application's",
132
+ "UUID to the local repository. It also automatically",
133
+ "figures out the git url from the application name so you don't",
134
+ "have to look it up."
135
+ syntax "<app> [--namespace namespace]"
136
+ option ["-n", "--namespace namespace"], "Namespace to add your application to", :context => :namespace_context, :required => true
137
+ argument :app, "The application you wish to clone", ["-a", "--app name"]
138
+ # TODO: Implement default values for arguments once ffranz has added context arguments
139
+ # argument :directory, "The name of a new directory to clone into", [], :default => nil
140
+ def git_clone(app)
141
+ rest_domain = rest_client.find_domain(options.namespace)
142
+ rest_app = rest_domain.find_application(app)
143
+ run_git_clone(rest_app)
144
+ 0
145
+ end
146
+
147
+ summary "Delete an application from the server"
148
+ description "Deletes your application and all of its data from the server.",
149
+ "Use with caution as this operation is permanent."
150
+ syntax "<app> [--namespace namespace]"
151
+ option ["-n", "--namespace namespace"], "Namespace to add your application to", :context => :namespace_context, :required => true
152
+ option ["-b", "--bypass"], "DEPRECATED Please use '--confirm'", :deprecated => {:key => :confirm, :value => true}
153
+ option ["--confirm"], "Deletes the application without prompting the user"
154
+ argument :app, "The application you wish to delete", ["-a", "--app name"]
155
+ alias_action :destroy, :deprecated => true
156
+ def delete(app)
157
+ rest_domain = rest_client.find_domain(options.namespace)
158
+ rest_app = rest_domain.find_application(app)
159
+ do_delete = true
160
+
161
+ do_delete = agree "Are you sure you wish to delete the '#{rest_app.name}' application? (yes/no)" unless options.confirm
162
+
163
+ if do_delete
164
+ paragraph { say "Deleting application '#{rest_app.name}'" }
165
+ rest_app.destroy
166
+ results { say "Application '#{rest_app.name}' successfully deleted" }
167
+ end
168
+ 0
169
+ end
170
+
171
+ summary "Start the application"
172
+ syntax "<app> [--namespace namespace] [--app app]"
173
+ argument :app, "The name of the application you are starting", ["-a", "--app app"], :context => :app_context
174
+ option ["-n", "--namespace namespace"], "Namespace of the application the cartridge belongs to", :context => :namespace_context, :required => true
175
+ def start(app)
176
+ app_action app, :start
177
+
178
+ results { say "#{app} started" }
179
+ 0
180
+ end
181
+
182
+ summary "Stop the application"
183
+ syntax "<app> [--namespace namespace] [--app app]"
184
+ argument :app, "The name of the application you are stopping", ["-a", "--app app"], :context => :app_context
185
+ option ["-n", "--namespace namespace"], "Namespace of the application the cartridge belongs to", :context => :namespace_context, :required => true
186
+ def stop(app)
187
+ app_action app, :stop
188
+
189
+ results { say "#{app} stopped" }
190
+ 0
191
+ end
192
+
193
+ summary "Stops all application processes"
194
+ syntax "<app> [--namespace namespace] [--app app]"
195
+ argument :app, "The name of the application you are stopping", ["-a", "--app app"], :context => :app_context
196
+ option ["-n", "--namespace namespace"], "Namespace of the application the cartridge belongs to", :context => :namespace_context, :required => true
197
+ def force_stop(app)
198
+ app_action app, :stop, true
199
+
200
+ results { say "#{app} force stopped" }
201
+ 0
202
+ end
203
+
204
+ summary "Restart the application"
205
+ syntax "<app> [--namespace namespace] [--app app]"
206
+ argument :app, "The name of the application you are restarting", ["-a", "--app app"], :context => :app_context
207
+ option ["-n", "--namespace namespace"], "Namespace of the application the cartridge belongs to", :context => :namespace_context, :required => true
208
+ def restart(app)
209
+ app_action app, :restart
210
+
211
+ results { say "#{app} restarted" }
212
+ 0
213
+ end
214
+
215
+ summary "Reload the application's configuration"
216
+ syntax "<app> [--namespace namespace] [--app app]"
217
+ argument :app, "The name of the application you are reloading", ["-a", "--app app"], :context => :app_context
218
+ option ["-n", "--namespace namespace"], "Namespace of the application the cartridge belongs to", :context => :namespace_context, :required => true
219
+ def reload(app)
220
+ app_action app, :reload
221
+
222
+ results { say "#{app} config reloaded" }
223
+ 0
224
+ end
225
+
226
+ summary "Clean out the application's logs and tmp directories and tidy up the git repo on the server"
227
+ syntax "<app> [--namespace namespace] [--app app]"
228
+ argument :app, "The name of the application you are tidying", ["-a", "--app app"], :context => :app_context
229
+ option ["-n", "--namespace namespace"], "Namespace of the application the cartridge belongs to", :context => :namespace_context, :required => true
230
+ def tidy(app)
231
+ app_action app, :tidy
232
+
233
+ results { say "#{app} cleaned up" }
234
+ 0
235
+ end
236
+
237
+ summary "Show information about an application"
238
+ syntax "<app> [--namespace namespace] [--app app]"
239
+ argument :app, "The name of the application you are getting information on", ["-a", "--app app"], :context => :app_context
240
+ option ["-n", "--namespace namespace"], "Namespace of the application the cartridge belongs to", :context => :namespace_context, :required => true
241
+ option ["--state"], "Get the current state of the application's gears"
242
+ def show(app)
243
+ rest_domain = rest_client.find_domain(options.namespace)
244
+ rest_app = rest_domain.find_application(app)
245
+ unless options.state
246
+ display_app(rest_app,rest_app.cartridges,rest_app.scalable_carts.first)
247
+ else
248
+ results do
249
+ rest_app.gear_groups.each do |gg|
250
+ say "Geargroup #{gg.cartridges.collect { |c| c['name'] }.join('+')} is #{gg.gears.first['state']}"
251
+ end
252
+ end
253
+ end
254
+ 0
255
+ end
256
+
257
+ summary "Show status of an application's gears"
258
+ syntax "<app> [--namespace namespace] [--app app]"
259
+ argument :app, "The name of the application you are getting information on", ["-a", "--app app"], :context => :app_context
260
+ option ["-n", "--namespace namespace"], "Namespace of the application the cartridge belongs to", :context => :namespace_context, :required => true
261
+ deprecated "rhc app show --state"
262
+ def status(app)
263
+ # TODO: add a way to deprecate this and alias to show --apache
264
+ options.state = true
265
+ show(app)
266
+ end
267
+
268
+ private
269
+ include RHC::GitHelpers
270
+ include RHC::CartridgeHelpers
271
+
272
+ def app_action(app, action, *args)
273
+ rest_domain = rest_client.find_domain(options.namespace)
274
+ rest_app = rest_domain.find_application(app)
275
+ result = rest_app.send action, *args
276
+ result
277
+ end
278
+
279
+ def create_app(name, cartridge, rest_domain, gear_size=nil, scale=nil)
280
+ app_options = {:cartridge => cartridge}
281
+ app_options[:gear_profile] = gear_size if gear_size
282
+ app_options[:scale] = scale if scale
283
+ app_options[:debug] = true if @debug
284
+
285
+ debug "Creating application '#{name}' with these options - #{app_options}.inspect"
286
+
287
+ rest_cartridge = find_cartridge rest_client, cartridge, "standalone"
288
+ app_options[:cartridge] = rest_cartridge.name
289
+
290
+ rest_app = rest_domain.add_application name, app_options
291
+
292
+ debug "'#{rest_app.name}' created"
293
+
294
+ rest_app
295
+ end
296
+
297
+ def dns_propagated?(host, sleep_time=2)
298
+ #
299
+ # Confirm that the host exists in DNS
300
+ #
301
+ debug "Start checking for application dns @ '#{host}'"
302
+
303
+ found = false
304
+
305
+ # Allow DNS to propagate
306
+ Kernel.sleep 5
307
+
308
+ # Now start checking for DNS
309
+ for i in 0..MAX_RETRIES-1
310
+ found = host_exist?(host)
311
+ break if found
312
+
313
+ say " retry # #{i+1} - Waiting for DNS: #{host}"
314
+ Kernel.sleep sleep_time.to_i
315
+ sleep_time *= DEFAULT_DELAY_THROTTLE
316
+ end
317
+
318
+ debug "End checking for application dns @ '#{host} - found=#{found}'"
319
+
320
+ found
321
+ end
322
+
323
+ def host_exist?(host)
324
+ # :nocov:
325
+ dns = Resolv::DNS.new
326
+ dns.getresources(host, Resolv::DNS::Resource::IN::A).any?
327
+ # :nocov:
328
+ end
329
+
330
+ def check_sshkeys!
331
+ wizard = RHC::SSHWizard.new(rest_client)
332
+ wizard.run
333
+ end
334
+
335
+ def run_git_clone(rest_app)
336
+ debug "Pulling new repo down"
337
+
338
+ check_sshkeys! unless options.noprompt
339
+
340
+ repo_dir = options.repo || rest_app.name
341
+ git_clone_repo rest_app.git_url, repo_dir
342
+
343
+ configure_git rest_app
344
+
345
+ true
346
+ end
347
+
348
+ def configure_git(rest_app)
349
+ debug "Configuring git repo"
350
+
351
+ repo_dir = options.repo || rest_app.name
352
+ Dir.chdir(repo_dir) do |dir|
353
+ git_config_set "rhc.app-uuid", rest_app.uuid
354
+ end
355
+ end
356
+
357
+ def jenkins_app_name
358
+ return "jenkins" if options.enable_jenkins == true or options.enable_jenkins == "true"
359
+ return options.enable_jenkins if options.enable_jenkins.is_a?(String)
360
+ nil
361
+ end
362
+
363
+ def check_jenkins(app_name, rest_domain)
364
+ debug "Checking if jenkins arguments are valid"
365
+ raise ArgumentError, "The --no-dns option can't be used in conjunction with --enable-jenkins when creating an application. Either remove the --no-dns option or first install your application with --no-dns and then use 'rhc cartridge add' to embed the Jenkins client." unless options.dns
366
+
367
+
368
+ begin
369
+ jenkins_rest_app = rest_domain.find_application(:framework => "jenkins-1.4")
370
+ rescue RHC::ApplicationNotFoundException
371
+ debug "No Jenkins apps found during check"
372
+
373
+ # app name and jenkins app name are the same
374
+ raise ArgumentError, "You have named both your main application and your Jenkins application '#{app_name}'. In order to continue you'll need to specify a different name with --enable-jenkins or choose
375
+ a different application name." if jenkins_app_name == app_name
376
+
377
+ # jenkins app name and existing app are the same
378
+ begin
379
+ rest_app = rest_domain.find_application(:name => jenkins_app_name)
380
+ raise ArgumentError, "You have named your Jenkins application the same as an existing application '#{app_name}'. In order to continue you'll need to specify a different name with --enable-jenkins or delete the current application using 'rhc app delete #{app_name}'"
381
+ rescue RHC::ApplicationNotFoundException
382
+ end
383
+
384
+ debug "Jenkins arguments valid"
385
+ return nil
386
+ end
387
+
388
+ say "Found existing Jenkins application: #{jenkins_rest_app.name}"
389
+ say "Ignoring user specified Jenkins app name : #{options.enable_jenkins}" if jenkins_rest_app.name != options.enable_jenkins and options.enable_jenkins.is_a?(String)
390
+
391
+ debug "Jenkins arguments valid"
392
+ jenkins_rest_app
393
+ end
394
+
395
+ def setup_jenkins_app(rest_domain)
396
+ debug "Creating a new jenkins application"
397
+ rest_app = create_app(jenkins_app_name, "jenkins-1.4", rest_domain)
398
+
399
+ say "Jenkins domain name is being propagated worldwide (this might take a minute)..."
400
+ # If we can't get the dns we can't install the client so return nil
401
+ dns_propagated?(rest_app.host) ? rest_app : nil
402
+
403
+ end
404
+
405
+ def setup_jenkins_client(rest_app)
406
+ rest_app.add_cartridge("jenkins-client-1.4", 300)
407
+ end
408
+
409
+ def run_nslookup(host)
410
+ # :nocov:
411
+ `nslookup #{host}`
412
+ $?.exitstatus == 0
413
+ # :nocov:
414
+ end
415
+
416
+ def run_ping(host)
417
+ # :nocov:
418
+ `ping #{host} -n 2`
419
+ $?.exitstatus == 0
420
+ # :nocov:
421
+ end
422
+
423
+ def windows_nslookup_bug?(rest_app)
424
+ windows_nslookup = run_nslookup(rest_app.host)
425
+ windows_ping = run_ping(rest_app.host)
426
+
427
+ if windows_nslookup and !windows_ping # this is related to BZ #826769
428
+ issue = <<WINSOCKISSUE
429
+ We were unable to lookup your hostname (#{rest_app.host})
430
+ in a reasonable amount of time. This can happen periodically and may
431
+ take up to 10 extra minutes to propagate depending on where you are in the
432
+ world. This may also be related to an issue with Winsock on Windows [1][2].
433
+ We recommend you wait a few minutes then clone your git repository manually.
434
+
435
+ [1] http://support.microsoft.com/kb/299357
436
+ [2] http://support.microsoft.com/kb/811259
437
+ WINSOCKISSUE
438
+ add_issue(issue,
439
+ "Clone your git repo",
440
+ "rhc app git-clone #{rest_app.name}")
441
+
442
+ return true
443
+ end
444
+
445
+ false
446
+ end
447
+
448
+ def output_issues(rest_app)
449
+ reasons, steps = format_issues(4)
450
+ warn <<WARNING_OUTPUT
451
+ !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
452
+ WARNING: Your application was created successfully but had problems during
453
+ configuration. Below is a list of the issues and steps you can
454
+ take to complete the configuration of your application.
455
+
456
+ Application URL: #{rest_app.app_url}
457
+
458
+ Issues:
459
+ #{reasons}
460
+ Steps to complete your configuration:
461
+ #{steps}
462
+ If you can't get your application '#{rest_app.name}' running in the browser,
463
+ you can try destroying and recreating the application:
464
+
465
+ $ rhc app delete #{rest_app.name} --confirm
466
+
467
+ If this doesn't work for you, let us know in the forums or in IRC and we'll
468
+ make sure to get you up and running.
469
+
470
+ Forums - https://openshift.redhat.com/community/forums/openshift
471
+ IRC - #openshift (on Freenode)
472
+
473
+ !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
474
+
475
+ WARNING_OUTPUT
476
+ end
477
+ end
478
+ end