rhc 0.81.14 → 0.82.18

Sign up to get free protection for your applications and to get access to all the features.
Files changed (6) hide show
  1. data/Rakefile +15 -3
  2. data/bin/rhc-chk +356 -124
  3. data/bin/rhc-create-app +21 -23
  4. data/bin/rhc-ctl-app +13 -8
  5. data/lib/rhc-common.rb +65 -47
  6. metadata +10 -10
data/Rakefile CHANGED
@@ -3,7 +3,13 @@
3
3
  require 'rubygems'
4
4
  require 'rake'
5
5
  require 'rake/clean'
6
- require 'rubygems/package_task'
6
+
7
+ begin
8
+ require 'rubygems/package_task'
9
+ rescue LoadError
10
+ require 'rake/gempackagetask'
11
+ rake_gempackage = true
12
+ end
7
13
 
8
14
  task :default => [:package]
9
15
 
@@ -31,8 +37,14 @@ spec = Gem::Specification.new do |s|
31
37
  end
32
38
 
33
39
  # Define a :package task that bundles the gem
34
- Gem::PackageTask.new(spec) do |pkg, args|
35
- pkg.need_tar = false
40
+ if rake_gempackage
41
+ Rake::GemPackageTask.new(spec) do |pkg, args|
42
+ pkg.need_tar = false
43
+ end
44
+ else
45
+ Gem::PackageTask.new(spec) do |pkg, args|
46
+ pkg.need_tar = false
47
+ end
36
48
  end
37
49
 
38
50
  # Add the 'pkg' directory to the clean task
@@ -25,14 +25,18 @@ require 'rhc-common'
25
25
  require 'net/http'
26
26
  require 'net/https'
27
27
  require 'rbconfig'
28
+ require 'yaml'
29
+ require 'tempfile'
28
30
 
31
+ require 'test/unit'
32
+ require 'test/unit/ui/console/testrunner'
29
33
 
30
34
  #
31
35
  # print help
32
36
  #
33
37
  def p_usage
34
- rhlogin = get_var('default_rhlogin') ? "Default: #{get_var('default_rhlogin')}" : "required"
35
- puts <<USAGE
38
+ rhlogin = get_var('default_rhlogin') ? "Default: #{get_var('default_rhlogin')}" : "required"
39
+ puts <<USAGE
36
40
 
37
41
  Usage: #{$0}
38
42
  Run a simple check on local configs and credentials to confirm tools are
@@ -50,177 +54,405 @@ exit 255
50
54
  end
51
55
 
52
56
  begin
53
- opts = GetoptLong.new(
54
- ["--debug", "-d", GetoptLong::NO_ARGUMENT],
55
- ["--help", "-h", GetoptLong::NO_ARGUMENT],
56
- ["--rhlogin", "-l", GetoptLong::REQUIRED_ARGUMENT],
57
- ["--password", "-p", GetoptLong::REQUIRED_ARGUMENT],
58
- ["--config", GetoptLong::REQUIRED_ARGUMENT],
59
- ["--timeout", GetoptLong::REQUIRED_ARGUMENT]
60
- )
61
- opt = {}
62
- opts.each do |o, a|
63
- opt[o[2..-1]] = a.to_s
64
- end
57
+ opts = GetoptLong.new(
58
+ ["--debug", "-d", GetoptLong::NO_ARGUMENT],
59
+ ["--help", "-h", GetoptLong::NO_ARGUMENT],
60
+ ["--rhlogin", "-l", GetoptLong::REQUIRED_ARGUMENT],
61
+ ["--password", "-p", GetoptLong::REQUIRED_ARGUMENT],
62
+ ["--config", GetoptLong::REQUIRED_ARGUMENT],
63
+ ["--timeout", GetoptLong::REQUIRED_ARGUMENT]
64
+ )
65
+ $opt = {}
66
+ opts.each do |o, a|
67
+ $opt[o[2..-1]] = a.to_s
68
+ end
65
69
  rescue Exception => e
66
70
  #puts e.message
67
- p_usage
71
+ p_usage
72
+ end
73
+
74
+ if $opt["help"]
75
+ p_usage
68
76
  end
69
77
 
78
+
70
79
  # If provided a config path, check it
71
- check_cpath(opt)
80
+ check_cpath($opt)
81
+
82
+ # Need to store the config information so tests can use it
83
+ # since they are technically new objects
84
+ $opts_config_path = @opts_config_path
85
+ $local_config_path = @local_config_path
86
+ $opts_config = @opts_config
87
+ $local_config = @local_config
88
+ $global_config = @global_config
72
89
 
73
90
  # Pull in configs from files
74
- @libra_server = get_var('libra_server')
75
- @debug = get_var('debug') == 'false' ? nil : get_var('debug')
91
+ $libra_server = get_var('libra_server')
92
+ $debug = get_var('debug') == 'false' ? nil : get_var('debug')
76
93
 
77
- if opt["help"]
78
- p_usage
79
- end
80
94
 
81
- if opt["debug"]
82
- @debug = true
95
+ if $opt["debug"]
96
+ $debug = true
83
97
  end
84
- RHC::debug(@debug)
98
+ RHC::debug($debug)
85
99
 
86
- RHC::timeout(opt["timeout"] ? opt["timeout"] : get_var('timeout'))
100
+ RHC::timeout($opt["timeout"] ? $opt["timeout"] : get_var('timeout'))
87
101
 
88
- opt["rhlogin"] = get_var('default_rhlogin') unless opt["rhlogin"]
89
- if !RHC::check_rhlogin(opt['rhlogin'])
90
- p_usage
102
+ $opt["rhlogin"] = get_var('default_rhlogin') unless $opt["rhlogin"]
103
+ if !RHC::check_rhlogin($opt['rhlogin'])
104
+ p_usage
91
105
  end
92
- @rhlogin = opt["rhlogin"]
106
+ $rhlogin = $opt["rhlogin"]
93
107
 
94
- @password = opt['password']
95
- if !@password
96
- @password = RHC::get_password
108
+ $password = $opt['password']
109
+ if !$password
110
+ $password = RHC::get_password
97
111
  end
98
112
 
99
113
  #
100
114
  # Generic Info
101
115
  #
102
- puts "Ruby Version: #{RUBY_VERSION}"
103
- puts "host_alias: #{Config::CONFIG['host_alias']}"
116
+ $debuginfo = {
117
+ 'environment' => {
118
+ 'Ruby Version' => RUBY_VERSION,
119
+ "host_alias" => Config::CONFIG['host_alias']
120
+ },
121
+ 'options' => {
122
+ "Command Line" => $opt,
123
+ "Opts" => $opts_config,
124
+ "Local" => $local_config,
125
+ "Global" => $global_config
126
+ }
127
+ }
128
+
129
+ # Don't actually log the password, but some information to help with troubleshooting
130
+ if $opt['password']
131
+ $debuginfo['options']['Command Line']['password'] = {
132
+ "Length" => $opt['password'].length,
133
+ "Starts with" => $opt['password'][0..0]
134
+ }
135
+ end
104
136
 
105
137
  #
106
138
  # Check for proxy environment
107
139
  #
108
140
  if ENV['http_proxy']
109
- host, port = ENV['http_proxy'].split(':')
110
- @http = Net::HTTP::Proxy(host, port)
111
- puts "Proxy being used: #{host}:#{port}"
141
+ if ENV['http_proxy']!~/^(\w+):\/\// then
142
+ ENV['http_proxy']="http://" + ENV['http_proxy']
143
+ end
144
+ proxy_uri=URI.parse(ENV['http_proxy'])
145
+ $http = Net::HTTP::Proxy(proxy_uri.host, proxy_uri.port, proxy_uri.user, proxy_uri.password)
146
+ $debuginfo['environment']['proxy'] = "#{proxy_uri.user}:#{proxy_uri.password}@#{proxy_uri.host}:#{proxy_uri.port}"
112
147
  else
113
- @http = Net::HTTP
114
- puts "Proxy being used: none"
148
+ $http = Net::HTTP
149
+ $debuginfo['environment']['proxy'] = "none"
115
150
  end
116
151
 
117
- def test_url_json(uri, data)
152
+ #####################################
153
+ # Done setting up environment #
154
+ #####################################
155
+
156
+ module TestBase
157
+ def initialize(*args)
158
+ super
159
+ $connectivity ||= false
160
+ # These need to be loaded for each test to be able to access them
161
+ @opts_config_path = $opts_config_path
162
+ @local_config_path = $local_config_path
163
+ @opts_config = $opts_config
164
+ @local_config = $local_config
165
+ @global_config = $global_config
166
+ end
167
+
168
+ def fetch_url_json(uri, data)
118
169
  json_data = RHC::generate_json(data)
119
- url = URI.parse("https://#{@libra_server}#{uri}")
120
- puts " Contacting URL: https://#{@libra_server}#{uri}" if @debug
121
- puts " json_data: #{json_data}" if @debug
122
- req = @http::Post.new(url.path)
123
- req.set_form_data({'json_data' => json_data, 'password' => @password})
124
- http = @http.new(url.host, url.port)
170
+ url = URI.parse("https://#{$libra_server}#{uri}")
171
+ req = $http::Post.new(url.path)
172
+ req.set_form_data({'json_data' => json_data, 'password' => $password})
173
+ http = $http.new(url.host, url.port)
125
174
  http.open_timeout = 10
126
175
  http.use_ssl = true
127
176
  http.verify_mode = OpenSSL::SSL::VERIFY_NONE
128
- response = nil
177
+
178
+ response = http.start {|http| http.request(req)}
179
+ return response
180
+ ensure
181
+ $debuginfo['fetches'] ||= []
182
+ body = JSON.parse(response.body)
183
+ body['data'] = body['data'] ? JSON.parse(body['data']) : ''
184
+ $debuginfo['fetches'] << {url.to_s => {
185
+ 'body' => body,
186
+ 'header' => response.instance_variable_get(:@header)
187
+ }}
188
+ end
189
+
190
+ def continue_test
129
191
  begin
130
- response = http.start {|http| http.request(req)}
131
- puts " Raw Response: #{response.body}" if @debug
132
- rescue Exception => e
133
- puts " ERROR: #{e.message}"
192
+ yield
193
+ rescue Test::Unit::AssertionFailedError => e
194
+ self.send(:add_failure,e.message,e.backtrace)
134
195
  end
135
- if response
136
- puts " Code: #{response.code}"
137
- puts " Message: #{response.message}"
138
- if response.code == '200'
139
- puts response.body
140
- resp_json = JSON.parse(response.body)
141
- return resp_json
142
- elsif response.code == '404' && data['rhlogin']
143
- puts "A user with rhlogin '#{data['rhlogin']}' does not have a registered domain."
144
- exit 99
145
- elsif response.code == '401'
146
- puts "Invalid user credentials"
147
- exit 97
148
- else
149
- puts "Exiting due to error!"
150
- exit 1
151
- end
196
+ end
197
+ end
198
+
199
+ #####################################################
200
+ # Tests start here #
201
+ #####################################################
202
+ # #
203
+ # Note: Tests and testcases are run alphabetically #
204
+ # #
205
+ #####################################################
206
+
207
+ def error_for(name,*args)
208
+ if name.kind_of? String
209
+ name = name.downcase.to_sym
210
+ end
211
+ sprintf($messages[name],*args)
212
+ end
213
+
214
+ class Test1_Connectivity < Test::Unit::TestCase
215
+ include TestBase
216
+ def teardown
217
+ # Set global variable in case we cannot connect to the server
218
+ if method_name == 'test_connectivity'
219
+ $connectivity = passed?
220
+ end
221
+ end
222
+
223
+ #
224
+ # Checking Connectivity / cart list
225
+ #
226
+ def test_connectivity
227
+ data = {'cart_type' => 'standalone'}
228
+
229
+ response = fetch_url_json("/broker/cartlist", data)
230
+ assert_equal 200, response.code.to_i, error_for(:no_connectivity, $libra_server)
231
+ end
232
+ end
233
+
234
+ class Test2_Authentication < Test::Unit::TestCase
235
+ include TestBase
236
+ #
237
+ # Checking Authentication
238
+ #
239
+ def test_authentication
240
+ assert $connectivity, error_for(:cant_connect)
241
+
242
+ data = {'rhlogin' => $rhlogin}
243
+ response = fetch_url_json("/broker/userinfo", data)
244
+ resp_json = JSON.parse(response.body)
245
+
246
+ case response.code.to_i
247
+ when 404
248
+ assert false, error_for(:_404, $rhlogin)
249
+ when 401
250
+ assert false, error_for(:_401, $rhlogin)
251
+ when 200
252
+ assert true
152
253
  else
153
- puts "Unable to connect to: https://#{@libra_server}"
154
- exit 1
254
+ assert false, error_for(:_other_http, resp_json['result'])
155
255
  end
256
+
257
+ $user_info = JSON.parse(resp_json['data'].to_s)
258
+ end
156
259
  end
157
260
 
158
261
  #
159
- # Checking Connectivity / cart list
262
+ # Checking ssh key
160
263
  #
161
- puts
162
- puts "TEST1: Confirming connection to OpenShift"
163
- data = {'cart_type' => 'standalone'}
264
+ class Test3_SSH < Test::Unit::TestCase
164
265
 
165
- resp_json = test_url_json("/broker/cartlist", data)
166
- puts " Cart Info: #{resp_json["data"]}"
266
+ @@local_derived_ssh_pubkey = nil
267
+ @@local_ssh_pubkey = nil
167
268
 
269
+ include TestBase
168
270
 
169
- #
170
- # Checking Authentication
171
- #
172
- puts
173
- puts "TEST2: Authentication (RHN account) / user info"
174
- data = {'rhlogin' => @rhlogin}
271
+ def setup
272
+ @libra_kfile = get_kfile(false)
273
+ if @libra_kfile
274
+ @libra_kpfile = get_kpfile(@libra_kfile, false)
275
+ end
276
+ end
175
277
 
176
- resp_json = test_url_json("/broker/userinfo", data)
177
- @user_info = JSON.parse(resp_json['data'].to_s)
178
- puts " rhlogin: #{@user_info["user_info"]["rhlogin"]}"
179
- puts " namespace: #{@user_info["user_info"]["namespace"]}"
278
+ def test_01_ssh_private_key
279
+ check_permissions(@libra_kfile, /[4-7]00/) # Needs to at least be readable by user and nobody else
180
280
 
181
- #
182
- # Checking ssh key
183
- #
184
- puts
185
- puts "TEST3: SSH Key check"
186
- remote_ssh_pubkey = @user_info["user_info"]["ssh_key"]
187
- libra_kfile = get_kfile()
188
- libra_kpfile = get_kpfile(libra_kfile, false)
189
-
190
- if File.exists?(libra_kfile)
191
- puts " OK: #{libra_kfile} - Found"
192
- key_dump = `ssh-keygen -f #{libra_kfile} -y`
193
- local_derived_ssh_pubkey = key_dump.to_s.strip.split(' ')[1]
194
- else
195
- puts " ERROR: #{libra_kfile} - Not Found!"
196
- end
281
+ # Derive the public key from the private key
282
+ key_dump = `ssh-keygen -f #{@libra_kfile} -y`
283
+ @@local_derived_ssh_pubkey = key_dump.to_s.strip.split(' ')[1]
197
284
 
198
- if File.exists?(libra_kpfile)
199
- puts " OK: #{libra_kpfile} Found"
200
- fp = File.open(libra_kpfile)
201
- local_ssh_pubkey = fp.gets.split(' ')[1]
202
- fp.close
203
- else
204
- puts " WARNING: #{libra_kpfile} Not Found! (non fatal error)"
205
- end
285
+ assert_not_nil @@local_derived_ssh_pubkey, error_for(:no_derive)
206
286
 
207
- if local_ssh_pubkey.to_s.strip == remote_ssh_pubkey.to_s.strip
208
- puts " OK: Remote and #{libra_kpfile} - match"
209
- else
210
- puts " WARNING: Remote and #{libra_kpfile} key do not match. (have you changed machines or ssh keys?)"
287
+ assert_not_nil $user_info, error_for(:no_account)
288
+ remote_ssh_pubkey = $user_info["user_info"]["ssh_key"]
289
+
290
+ assert_match @@local_derived_ssh_pubkey, remote_ssh_pubkey, error_for(:no_match_pub, @libra_kfile)
291
+ end
292
+
293
+ def test_02_ssh_public_key
294
+ check_permissions(@libra_kpfile, /.../) # Any permissions are OK
295
+
296
+ # Store the public key
297
+ fp = File.open(@libra_kpfile)
298
+ @@local_ssh_pubkey = fp.gets.split(' ')[1]
299
+
300
+ assert_not_nil @@local_ssh_pubkey, error_for(:no_pubkey, 'the remote key')
301
+
302
+ assert_not_nil $user_info, error_for(:no_account)
303
+ remote_ssh_pubkey = $user_info["user_info"]["ssh_key"]
304
+
305
+ # Test public key and remote key
306
+ assert_match @@local_ssh_pubkey, remote_ssh_pubkey, error_for(:no_match_pub,@libra_kpfile)
307
+ ensure
308
+ fp.close if fp
309
+ end
310
+
311
+ def test_05_ssh_config
312
+ check_permissions('~/.ssh/config',/600/)
313
+ end
314
+
315
+ def test_06_ssh_agent
316
+ loaded_keys = `ssh-add -L`.to_a
317
+ # Make sure we can load keys from ssh-agent
318
+ assert !loaded_keys.empty?, error_for(:no_keys_loaded)
319
+ loaded_keys.map!{|key| key.split(' ')[1]}
320
+
321
+ assert_not_nil @@local_ssh_pubkey, error_for(:no_pubkey, 'the keys in ssh-agent')
322
+ assert loaded_keys.include?(@@local_ssh_pubkey),error_for(:pubkey_not_loaded)
323
+ end
324
+
325
+ def test_07_ssh_connect
326
+ assert_not_nil $user_info, error_for(:no_account)
327
+ host_template = "%s@%s-%s.%s"
328
+ $user_info['app_info'].each do |k,v|
329
+ uuid = v['uuid']
330
+ host = sprintf("%s-%s",k,$user_info['user_info']['namespace'])
331
+ domain = $user_info['user_info']['rhc_domain']
332
+ ssh_command = sprintf("ssh %s@%s.%s true &> /dev/null", uuid, host, domain)
333
+ system(ssh_command)
334
+ continue_test{ assert_equal $?, 0, error_for(:cant_ssh, host) }
335
+ end
336
+ end
337
+
338
+ private
339
+ def check_permissions(file,permission)
340
+ file = File.expand_path(file)
341
+
342
+ assert File.exists?(file), error_for(:file_not_found,file)
343
+
344
+ perms = sprintf('%o',File.stat(file).mode)[-3..-1]
345
+
346
+ assert_match permission, perms, error_for(:bad_permissions,file,perms,permission.source)
347
+ end
211
348
  end
212
349
 
213
- if local_derived_ssh_pubkey.to_s.strip == remote_ssh_pubkey.to_s.strip
214
- puts " OK: local #{libra_kfile} should auth with openshift"
215
- else
216
- puts " WARNING: local #{libra_kpfile} DOES NOT match remote pub key, ssh auth cannot continue"
217
- puts " FIX: Perhaps you should regenerate your public key, or run rhc-create-domain with -a to alter the remote key"
350
+ ############################################################
351
+ # Below this line is the custom Test::Runner code #
352
+ # Modification should not be necessary to add/modify tests #
353
+ ############################################################
354
+
355
+ class CheckRunner < Test::Unit::UI::Console::TestRunner
356
+ def initialize(*args)
357
+ super
358
+ @output_level = 1
359
+ puts $messages[:started]
360
+ end
361
+
362
+ def add_fault(fault)
363
+ @faults << fault
364
+ print(fault.single_character_display)
365
+ @already_outputted = true
366
+ end
367
+
368
+ def print_underlined(string)
369
+ string = "|| #{string} ||"
370
+ line = "=" * string.length
371
+ puts
372
+ puts line
373
+ puts string
374
+ puts line
375
+ end
376
+
377
+ def render_message(message)
378
+ lines = message.to_a
379
+ message = []
380
+ @num ||= 0
381
+ message << "#{@num+=1}) #{lines.shift.strip}"
382
+ lines.each do |line|
383
+ # Break if we get the standard assert error information or a blank line
384
+ break if line.match(/^\<.*?> /) or line.match(/^\s*$/)
385
+ message << "\t#{line.strip}"
386
+ end
387
+ message.join("\n")
388
+ end
389
+
390
+ def finished(*args)
391
+ super
392
+ $debuginfo['errors'] = @faults
393
+
394
+ if @faults.empty?
395
+ print_underlined $messages[:passed]
396
+ else
397
+ print_underlined $messages[:failed]
398
+ @errors = []
399
+ # Need to separate the failures from the errors
400
+
401
+ @faults.each do |f|
402
+ case f
403
+ when Test::Unit::Failure
404
+ puts render_message(f.message)
405
+ when Test::Unit::Error
406
+ @errors << f
407
+ end
408
+ end
409
+
410
+ # Errors mean something in the test is broken, not just failed
411
+ unless @errors.empty?
412
+ @num = 0
413
+ print_underlined $messages[:error]
414
+ @errors.each do |e|
415
+ lines = e.long_display.to_a[1..-1]
416
+ puts "#{@num+=1}) #{lines.shift}"
417
+ lines.each{|l| puts "\t#{l}"}
418
+ end
419
+ end
420
+
421
+ end
422
+
423
+ if $debug
424
+ Tempfile.open(%w(rhc-chk. .log))do |file|
425
+ ObjectSpace.undefine_finalizer(file) # persist tempfile
426
+ file.write $debuginfo.to_yaml
427
+ puts
428
+ puts "Debugging information dumped to #{file.path}"
429
+ end
430
+ end
431
+ end
218
432
  end
219
433
 
220
- if @debug
221
- puts "remote_ssh_pubkey: #{remote_ssh_pubkey}"
222
- puts "local_ssh_pubkey: #{local_ssh_pubkey}"
223
- puts "local_derived_ssh_pubkey: #{local_derived_ssh_pubkey}"
434
+ Test::Unit::AutoRunner::RUNNERS[:console] = proc do |r|
435
+ CheckRunner
224
436
  end
225
437
 
226
- exit 0
438
+ $messages = YAML.load <<-EOF
439
+ ---
440
+ :started: Analyzing system
441
+ :passed: Congratulations, your system has passed all tests
442
+ :failed: Your system did not pass all of the tests
443
+ :error: Something went wrong, and not all tests completed
444
+ :no_derive: "We were unable to derive your public SSH key and compare it to the remote\n FIX: ???"
445
+ :no_connectivity: "Cannot connect to server, therefore most tests will not work\n FIX: Ensure that you are able to connect to %s"
446
+ :no_account: You must have an account on the server in order to test SSH key matches
447
+ :cant_connect: You need to be able to connect to the server in order to test authentication
448
+ :no_match_pub: "Local %s does not match remote pub key, SSH auth will not work\n FIX: Perhaps you should regenerate your public key, or run rhc-create-domain with -a to alter the remote key"
449
+ :_404: "The user %s does not have an account on this server\n FIX: Please ensure that you've entered the correct username"
450
+ :no_pubkey: We were unable to read your public SSH key to compare to %s
451
+ :_401: "Invalid user credentials for %s\n FIX: Please ensure you used the correct password"
452
+ :file_not_found: File %s does not exist, cannot check permissions
453
+ :_other_http: "There was an error communicating with the server: %s"
454
+ :bad_permissions: "File %s has incorrect permissions %s\n FIX: Permissions should match %s"
455
+ :no_keys_loaded: Either ssh-agent is not running or you do not have any keys loaded
456
+ :pubkey_not_loaded: Your public key is not loaded into a running ssh-agent
457
+ :cant_ssh: "Cannot SSH into your app: %s"
458
+ EOF
@@ -40,7 +40,7 @@ Create an OpenShift Express app.
40
40
  -n|--nogit Only create remote space, don't pull it locally
41
41
  -d|--debug Print Debug info
42
42
  -h|--help Show Usage info
43
- --no-dns Skip DNS check
43
+ --no-dns Skip DNS check. Must be used in combination with --nogit
44
44
  --config path Path of alternate config file
45
45
  --timeout # Timeout, in seconds, for connection
46
46
  --enable-jenkins [name] Indicates to create a Jenkins application (if not already available)
@@ -119,10 +119,16 @@ if !password
119
119
  end
120
120
 
121
121
  user_info = RHC::get_user_info(libra_server, opt['rhlogin'], password, @http, false)
122
+ app_info = user_info['app_info']
123
+
124
+ if app_info[opt['app']]
125
+ puts "An application named '#{opt['app']}' in namespace '#{user_info['user_info']['namespace']}' already exists"
126
+ exit 255
127
+ end
128
+
122
129
  jenkins_app_name = nil
123
130
  has_jenkins = false
124
131
  if opt['enable-jenkins']
125
- app_info = user_info['app_info']
126
132
  app_info.each do |app_name, app|
127
133
  if app['framework'] == 'jenkins-1.4'
128
134
  jenkins_app_name = app_name
@@ -181,12 +187,14 @@ end
181
187
 
182
188
  opt['repo'] = opt['app'] unless opt['repo']
183
189
 
184
- puts "
185
- Found a bug? Post to the forum and we'll get right on it.
186
- IRC: #openshift on freenode
187
- Forums: https://www.redhat.com/openshift/forums
188
-
189
- "
190
+ if @mydebug
191
+ puts "
192
+ Found a bug? Post to the forum and we'll get right on it.
193
+ IRC: #openshift on freenode
194
+ Forums: https://www.redhat.com/openshift/forums
195
+
196
+ "
197
+ end
190
198
 
191
199
  #
192
200
  # Confirm local git repo exists
@@ -216,14 +224,7 @@ unless opt['nogit']
216
224
  end
217
225
 
218
226
  if jenkins_app_name && !has_jenkins
219
- jenkins_no_git_message = "
220
-
221
- Note: There is a git repo for your Jenkins application '#{jenkins_app_name}'
222
- but it isn't being downloaded as part of this process. In most cases
223
- it isn't needed but you can always clone it later.
224
-
225
- "
226
- jenkins_app = RHC::create_app(libra_server, @http, user_info, jenkins_app_name, 'jenkins-1.4', opt['rhlogin'], password, nil, false, true, jenkins_no_git_message)
227
+ jenkins_app = RHC::create_app(libra_server, @http, user_info, jenkins_app_name, 'jenkins-1.4', opt['rhlogin'], password, nil, false, true, true)
227
228
  available = RHC::check_app_available(@http, jenkins_app[:app_name], jenkins_app[:fqdn], jenkins_app[:health_check_path], jenkins_app[:result], jenkins_app[:git_url], nil, true)
228
229
  if !available
229
230
  puts "Unable to access your new Jenkins application."
@@ -234,13 +235,10 @@ end
234
235
  #
235
236
  # Create remote application space
236
237
  #
237
- main_app = RHC::create_app(libra_server, @http, user_info, opt['app'], opt['type'], opt['rhlogin'], password, opt['repo'], opt['no-dns'], opt['nogit'])
238
+ main_app = RHC::create_app(libra_server, @http, user_info, opt['app'], opt['type'], opt['rhlogin'], password, opt['repo'], opt['no-dns'], opt['nogit'], false)
238
239
  if jenkins_app_name
239
- puts "
240
- Now embedding the jenkins client into '#{opt['app']}'...
241
-
242
- "
243
- RHC::ctl_app(libra_server, @http, opt['app'], opt['rhlogin'], password, 'configure', true, 'jenkins-client-1.4')
240
+ puts "Now embedding the jenkins client into '#{opt['app']}'..."
241
+ RHC::ctl_app(libra_server, @http, opt['app'], opt['rhlogin'], password, 'configure', true, 'jenkins-client-1.4', nil, false)
244
242
  end
245
243
 
246
244
  unless opt['no-dns']
@@ -249,4 +247,4 @@ unless opt['no-dns']
249
247
  puts "Unable to access your new application."
250
248
  exit 1
251
249
  end
252
- end
250
+ end
@@ -35,7 +35,7 @@ Control an OpenShift express app
35
35
  -a|--app application Application name (alphanumeric) (required)
36
36
  -l|--rhlogin rhlogin Red Hat login (RHN or OpenShift login with OpenShift Express access) (#{rhlogin})
37
37
  -p|--password password RHLogin password (optional, will prompt)
38
- -c|--command command (start|stop|force-stop|restart|reload|status|destroy|add-alias|remove-alias)
38
+ -c|--command command (start|stop|force-stop|restart|reload|status|destroy|tidy|add-alias|remove-alias)
39
39
  -L|--embedded-list List supported embedded cartridges
40
40
  -e|--embed (add|remove|stop|start|restart|status|reload)-$cartridge eg: add-mysql-5.1
41
41
  -b|--bypass Bypass warnings
@@ -123,14 +123,14 @@ unless opt["embed"] or opt["command"]
123
123
  end
124
124
 
125
125
  if opt["command"]
126
- unless opt["command"] =~ /^(start|stop|force-stop|restart|reload|status|destroy|add-alias|remove-alias)$/
127
- puts "Invalid command '#{opt["command"]}' specified. Valid commands are (start|stop|force-stop|restart|reload|status|destroy|add-alias|remove-alias)"
126
+ unless opt["command"] =~ /^(start|stop|force-stop|restart|reload|status|destroy|tidy|add-alias|remove-alias)$/
127
+ puts "Invalid command '#{opt["command"]}' specified. Valid commands are (start|stop|force-stop|restart|reload|status|destroy|tidy|add-alias|remove-alias)"
128
128
  p_usage
129
129
  end
130
130
  elsif opt["embed"]
131
131
  action = opt['embed'].split('-')[0]
132
132
  unless action =~ /^(add|remove|start|stop|restart|status|reload)$/
133
- puts "Invalid embed action '#{action}' specified. Valid embed actions are (add|remove|start|stop|restart|status|reload|add-alias|remove-alias)"
133
+ puts "Invalid embed action '#{action}' specified. Valid embed actions are (add|remove|start|stop|restart|status|reload)"
134
134
  p_usage
135
135
  end
136
136
  end
@@ -165,10 +165,15 @@ This is NOT reversible, all remote data for this application will be removed.
165
165
  WARNING
166
166
 
167
167
  print "Do you want to destroy this application (y/n): "
168
- agree = gets.chomp
169
- if agree != 'y'
170
- puts "Destroy aborted"
171
- exit 217
168
+ begin
169
+ agree = gets.chomp
170
+ if agree != 'y'
171
+ puts "\n"
172
+ exit 217
173
+ end
174
+ rescue Interrupt
175
+ puts "\n"
176
+ exit 217
172
177
  end
173
178
  end
174
179
 
@@ -42,6 +42,13 @@ module RHC
42
42
  @mydebug = false
43
43
  broker_version = "?.?.?"
44
44
  api_version = "?.?.?"
45
+
46
+ # reset lines
47
+ # \r moves the cursor to the beginning of line
48
+ # ANSI escape code to clear line from cursor to end of line
49
+ # "\e" is an alternative to "\033"
50
+ # cf. http://en.wikipedia.org/wiki/ANSI_escape_code
51
+ CLEAR_LINE = "\r" + "\e[0K"
45
52
 
46
53
  DEBUG_INGORE_KEYS = {
47
54
  'result' => nil,
@@ -276,7 +283,8 @@ module RHC
276
283
  end
277
284
  exit_code = 1
278
285
  if response.content_type == 'application/json'
279
- puts "JSON response:"
286
+ print "JSON response:"
287
+ $stdout.flush
280
288
  begin
281
289
  json_resp = JSON.parse(response.body)
282
290
  exit_code = print_json_body(json_resp)
@@ -301,7 +309,8 @@ module RHC
301
309
 
302
310
  def self.print_response_success(json_resp, print_result=false)
303
311
  if @mydebug
304
- puts "Response from server:"
312
+ print "Response from server:"
313
+ $stdout.flush
305
314
  print_json_body(json_resp, print_result)
306
315
  elsif print_result
307
316
  print_json_body(json_resp)
@@ -353,8 +362,8 @@ module RHC
353
362
  return resp.any?
354
363
  end
355
364
 
356
- def self.create_app(libra_server, net_http, user_info, app_name, app_type, rhlogin, password, repo_dir=nil, no_dns=false, no_git=false, no_git_message=nil)
357
- puts "Attempting to create remote application space: #{app_name}"
365
+ def self.create_app(libra_server, net_http, user_info, app_name, app_type, rhlogin, password, repo_dir=nil, no_dns=false, no_git=false, is_embedded_jenkins=false)
366
+ puts "Creating application: #{app_name}"
358
367
 
359
368
  data = {:cartridge => app_type,
360
369
  :action => 'configure',
@@ -412,11 +421,17 @@ module RHC
412
421
  while loop < MAX_RETRIES && !hostexist?(fqdn)
413
422
  sleep sleep_time
414
423
  loop+=1
415
- puts " retry # #{loop} - Waiting for DNS: #{fqdn}"
424
+ print CLEAR_LINE + " retry # #{loop} - Waiting for DNS: #{fqdn}"
425
+ $stdout.flush
416
426
  sleep_time = delay(sleep_time)
417
427
  end
418
428
  end
419
429
 
430
+ # if we have executed print statements, then move to the next line
431
+ if loop > 0
432
+ puts
433
+ end
434
+
420
435
  # If the hostname couldn't be resolved, print out the git URL
421
436
  # and exit cleanly. This will help solve issues where DNS times
422
437
  # out in APAC, etc on resolution.
@@ -461,7 +476,7 @@ WARNING
461
476
  git_url = "ssh://#{app_uuid}@#{app_name}-#{namespace}.#{rhc_domain}/~/git/#{app_name}.git/"
462
477
 
463
478
  unless no_git
464
- puts "Pulling new repo down"
479
+ puts "Pulling new repo down" if @mydebug
465
480
 
466
481
  puts "git clone --quiet #{git_url} #{repo_dir}" if @mydebug
467
482
  quiet = (@mydebug ? ' ' : '--quiet ')
@@ -472,8 +487,17 @@ WARNING
472
487
  exit 216
473
488
  end
474
489
  else
475
- if no_git_message
476
- puts no_git_message
490
+ if is_embedded_jenkins
491
+ # if this is a jenkins client application to be embedded,
492
+ # then print this message only in debug mode
493
+ if @mydebug
494
+ puts "
495
+ Note: There is a git repo for your Jenkins application '#{app_name}'
496
+ but it isn't being downloaded as part of this process. In most cases
497
+ it isn't needed but you can always clone it later.
498
+
499
+ "
500
+ end
477
501
  else
478
502
  puts <<IMPORTANT
479
503
 
@@ -514,51 +538,43 @@ IMPORTANT
514
538
  #
515
539
  sleep_time = 2
516
540
  attempt = 0
517
- puts "Confirming application '#{app_name}' is available"
541
+ puts "Confirming application '#{app_name}' is available" if @mydebug
518
542
  while attempt < MAX_RETRIES
519
543
  attempt += 1
520
- puts " Attempt # #{attempt}"
544
+ if @mydebug
545
+ puts " Attempt # #{attempt}"
546
+ else
547
+ print CLEAR_LINE + "Confirming application '#{app_name}' is available: Attempt # #{attempt}"
548
+ end
549
+ $stdout.flush
521
550
  url = URI.parse("http://#{fqdn}/#{health_check_path}")
551
+
552
+ sleep(2.0)
522
553
  begin
523
554
  response = net_http.get_response(url)
524
555
  rescue Exception => e
525
556
  response = nil
526
557
  end
527
558
  if !response.nil? && response.code == "200" && response.body[0,1] == "1"
528
- puts <<LOOKSGOOD
529
-
530
- Success! Your application '#{app_name}' is now published here:
531
-
532
- http://#{fqdn}/
533
-
534
- The remote repository is located here:
535
-
536
- #{git_url}
537
-
538
- LOOKSGOOD
539
- unless no_git
540
- puts <<LOOKSGOOD
541
- To make changes to '#{app_name}', commit to #{repo_dir}/.
542
- LOOKSGOOD
543
- else
544
- puts <<LOOKSGOOD
559
+ puts CLEAR_LINE + "Confirming application '#{app_name}' is available: Success!"
560
+ puts ""
561
+ puts "#{app_name} published: http://#{fqdn}/"
562
+ puts "git url: #{git_url}"
563
+
564
+ if @mydebug
565
+ unless no_git
566
+ puts "To make changes to '#{app_name}', commit to #{repo_dir}/."
567
+ else
568
+ puts <<LOOKSGOOD
545
569
  To make changes to '#{app_name}', you must first clone it with:
546
-
547
- git clone #{git_url}
548
-
549
- LOOKSGOOD
550
- puts <<LOOKSGOOD
551
- Then run 'git push' to update your OpenShift Express space.
570
+ git clone #{git_url}
552
571
 
553
572
  LOOKSGOOD
573
+ puts "Then run 'git push' to update your OpenShift Express space."
574
+ end
554
575
  end
555
576
  if result && !result.empty?
556
-
557
- puts <<LOOKSGOOD
558
-
559
- #{result}
560
-
561
- LOOKSGOOD
577
+ puts "#{result}"
562
578
  end
563
579
  return true
564
580
  end
@@ -566,8 +582,7 @@ LOOKSGOOD
566
582
  puts "Server responded with #{response.code}"
567
583
  puts response.body unless response.code == '503'
568
584
  end
569
- puts
570
- puts " sleeping #{sleep_time} seconds"
585
+ puts " sleeping #{sleep_time} seconds" if @mydebug
571
586
  sleep sleep_time
572
587
  sleep_time = delay(sleep_time)
573
588
  end
@@ -584,7 +599,7 @@ LOOKSGOOD
584
599
  http_post(net_http, url, json_data, password)
585
600
  end
586
601
 
587
- def self.ctl_app(libra_server, net_http, app_name, rhlogin, password, action, embedded=false, framework=nil, server_alias=nil)
602
+ def self.ctl_app(libra_server, net_http, app_name, rhlogin, password, action, embedded=false, framework=nil, server_alias=nil, print_result=true)
588
603
  data = {:action => action,
589
604
  :app_name => app_name,
590
605
  :rhlogin => rhlogin
@@ -610,8 +625,8 @@ LOOKSGOOD
610
625
  response = http_post(net_http, url, json_data, password)
611
626
 
612
627
  if response.code == '200'
613
- json_resp = JSON.parse(response.body)
614
- print_response_success(json_resp, true)
628
+ json_resp = JSON.parse(response.body)
629
+ print_response_success(json_resp, print_result || @mydebug)
615
630
  else
616
631
  print_response_err(response)
617
632
  end
@@ -662,8 +677,11 @@ end
662
677
  # Check for proxy environment
663
678
  #
664
679
  if ENV['http_proxy']
665
- host, port = ENV['http_proxy'].split(':')
666
- @http = Net::HTTP::Proxy(host, port)
680
+ if ENV['http_proxy']!~/^(\w+):\/\// then
681
+ ENV['http_proxy']="http://" + ENV['http_proxy']
682
+ end
683
+ proxy_uri=URI.parse(ENV['http_proxy'])
684
+ @http = Net::HTTP::Proxy(proxy_uri.host, proxy_uri.port, proxy_uri.user, proxy_uri.password)
667
685
  else
668
686
  @http = Net::HTTP
669
687
  end
@@ -761,4 +779,4 @@ def get_kpfile(kfile, check_exists=true)
761
779
  kfile_not_found
762
780
  end
763
781
  return kpfile
764
- end
782
+ end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rhc
3
3
  version: !ruby/object:Gem::Version
4
- hash: 327
4
+ hash: 371
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
- - 81
9
- - 14
10
- version: 0.81.14
8
+ - 82
9
+ - 18
10
+ version: 0.82.18
11
11
  platform: ruby
12
12
  authors:
13
13
  - Red Hat
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2011-11-10 00:00:00 Z
18
+ date: 2011-12-01 00:00:00 Z
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
21
21
  name: json_pure
@@ -61,13 +61,13 @@ extra_rdoc_files: []
61
61
 
62
62
  files:
63
63
  - lib/rhc-common.rb
64
- - bin/rhc-ctl-app
65
- - bin/rhc-tail-files
66
64
  - bin/rhc-create-app
67
65
  - bin/rhc-chk
68
- - bin/rhc-snapshot
69
- - bin/rhc-create-domain
70
66
  - bin/rhc-user-info
67
+ - bin/rhc-create-domain
68
+ - bin/rhc-snapshot
69
+ - bin/rhc-ctl-app
70
+ - bin/rhc-tail-files
71
71
  - conf/express.conf
72
72
  - LICENSE
73
73
  - README
@@ -101,7 +101,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
101
101
  requirements: []
102
102
 
103
103
  rubyforge_project:
104
- rubygems_version: 1.7.2
104
+ rubygems_version: 1.8.11
105
105
  signing_key:
106
106
  specification_version: 3
107
107
  summary: OpenShift Express Client Tools