rhc 0.93.19 → 0.94.8
Sign up to get free protection for your applications and to get access to all the features.
- data/bin/rhc +53 -43
- data/bin/rhc-app +17 -14
- data/bin/rhc-chk +116 -48
- data/bin/rhc-create-app +1 -1
- data/bin/rhc-create-domain +0 -15
- data/lib/rhc-common.rb +47 -64
- data/lib/rhc-rest.rb +4 -8
- data/lib/rhc-rest/client.rb +1 -0
- data/lib/rhc-rest/exceptions/exceptions.rb +2 -2
- data/lib/rhc/client.rb +2 -0
- data/lib/rhc/config.rb +18 -9
- data/lib/rhc/json.rb +0 -1
- data/lib/rhc/targz.rb +1 -2
- data/lib/rhc/vendor/parseconfig.rb +178 -0
- data/lib/rhc/wizard.rb +12 -4
- data/spec/rhc/wizard_spec.rb +366 -145
- metadata +219 -213
data/bin/rhc
CHANGED
@@ -37,53 +37,63 @@ def get_args
|
|
37
37
|
args
|
38
38
|
end
|
39
39
|
|
40
|
+
def run_setup_wizard_if_needed
|
41
|
+
default_setup_wizard unless ARGV.include?('--noprompt')
|
42
|
+
end
|
40
43
|
|
41
|
-
|
44
|
+
begin
|
45
|
+
case ARGV[0]
|
46
|
+
when "domain"
|
47
|
+
run_setup_wizard_if_needed
|
48
|
+
system("rhc-domain #{get_args} 2>&1")
|
49
|
+
retcode = $?.exitstatus
|
50
|
+
when "app"
|
51
|
+
run_setup_wizard_if_needed
|
52
|
+
system("rhc-app #{get_args} 2>&1")
|
53
|
+
retcode = $?.exitstatus
|
54
|
+
when "sshkey"
|
55
|
+
run_setup_wizard_if_needed
|
56
|
+
system("rhc-sshkey #{get_args} 2>&1")
|
57
|
+
retcode = $?.exitstatus
|
58
|
+
when "port-forward"
|
59
|
+
run_setup_wizard_if_needed
|
60
|
+
system("rhc-port-forward #{get_args} 2>&1")
|
61
|
+
retcode = $?.exitstatus
|
62
|
+
when "server"
|
63
|
+
run_setup_wizard_if_needed
|
64
|
+
begin
|
65
|
+
require 'rhc/cli'
|
66
|
+
RHC::CLI.start(ARGV)
|
67
|
+
retcode = 0
|
68
|
+
rescue SystemExit => e
|
69
|
+
retcode = e.status
|
70
|
+
end
|
71
|
+
when "setup"
|
72
|
+
if ARGV.include?('--help') or ARGV.include?('-h') or ARGV.include?('help')
|
73
|
+
puts "Usage: rhc setup"
|
74
|
+
puts "Runs the setup wizard to configure your account"
|
75
|
+
exit 0
|
76
|
+
end
|
42
77
|
|
43
|
-
|
44
|
-
|
45
|
-
system("rhc-domain #{get_args} 2>&1")
|
46
|
-
retcode = $?.exitstatus
|
47
|
-
when "app"
|
48
|
-
system("rhc-app #{get_args} 2>&1")
|
49
|
-
retcode = $?.exitstatus
|
50
|
-
when "sshkey"
|
51
|
-
system("rhc-sshkey #{get_args} 2>&1")
|
52
|
-
retcode = $?.exitstatus
|
53
|
-
when "port-forward"
|
54
|
-
system("rhc-port-forward #{get_args} 2>&1")
|
55
|
-
retcode = $?.exitstatus
|
56
|
-
when "server"
|
57
|
-
begin
|
58
|
-
require 'rhc/cli'
|
59
|
-
RHC::CLI.start(ARGV)
|
78
|
+
w = RHC::RerunWizard.new(RHC::Config.local_config_path)
|
79
|
+
success = w.run
|
60
80
|
retcode = 0
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
puts "Runs the setup wizard to configure your account"
|
68
|
-
exit 0
|
81
|
+
retcode = 1 unless success
|
82
|
+
when "-h", "--help", "help", nil
|
83
|
+
p_usage 0
|
84
|
+
else
|
85
|
+
puts "Invalid rhc command: #{ARGV[0]}"
|
86
|
+
p_usage
|
69
87
|
end
|
70
|
-
exit 0 if wizard_run
|
71
|
-
w = RHC::RerunWizard.new(RHC::Config.local_config_path)
|
72
|
-
success = w.run
|
73
|
-
retcode = 0
|
74
|
-
retcode = 1 unless success
|
75
|
-
when "-h", "--help", "help", nil
|
76
|
-
p_usage 0
|
77
|
-
else
|
78
|
-
puts "Invalid rhc command: #{ARGV[0]}"
|
79
|
-
p_usage
|
80
|
-
end
|
81
88
|
|
82
|
-
if retcode == nil
|
83
|
-
|
89
|
+
if retcode == nil
|
90
|
+
retcode = 1
|
84
91
|
|
85
|
-
|
86
|
-
|
87
|
-
end
|
92
|
+
# return codes for uncaught signals are 128 + the signal code
|
93
|
+
retcode = 128 + $?.termsig if $?.signaled? and !$?.termsig.nil?
|
94
|
+
end
|
88
95
|
|
89
|
-
exit retcode
|
96
|
+
exit retcode
|
97
|
+
rescue Interrupt
|
98
|
+
exit 128 + 2 #INT
|
99
|
+
end
|
data/bin/rhc-app
CHANGED
@@ -17,10 +17,10 @@ Usage: rhc app (<command> | cartridge <cartridge-action> | --help) [<args>]
|
|
17
17
|
Create and manage an OpenShift application.
|
18
18
|
|
19
19
|
List of commands
|
20
|
-
create
|
20
|
+
create Create a new application on OpenShift
|
21
21
|
show Display information about a user
|
22
|
-
start Starts the application (includes
|
23
|
-
stop Stops the application (includes
|
22
|
+
start Starts the application (includes all cartridges)
|
23
|
+
stop Stops the application (includes all cartridges)
|
24
24
|
force-stop Stops all application processes
|
25
25
|
restart Restart the application
|
26
26
|
reload Reloads application configuration
|
@@ -32,17 +32,17 @@ List of commands
|
|
32
32
|
threaddump Trigger a thread dump for jbossas, jbosseap, and ruby applications
|
33
33
|
tail Tail the logs of an application
|
34
34
|
snapshot [save|restore] Saves/Restores an application snapshot to/from a tarball at the location specified using --filepath (default: ./$APPNAME.tar.gz)
|
35
|
-
cartridge <action> Manage
|
35
|
+
cartridge <action> Manage a cartridge runningin this application
|
36
36
|
|
37
37
|
List of cartridge actions
|
38
38
|
list List of supported embedded cartridges
|
39
|
-
add Add
|
40
|
-
remove Remove
|
41
|
-
stop Stop
|
42
|
-
start Start
|
43
|
-
restart Restart
|
44
|
-
status Returns
|
45
|
-
reload Reloads
|
39
|
+
add Add a cartridge to this application
|
40
|
+
remove Remove a cartridge from this application
|
41
|
+
stop Stop a cartridge
|
42
|
+
start Start a cartridge
|
43
|
+
restart Restart a cartridge
|
44
|
+
status Returns cartridge status
|
45
|
+
reload Reloads cartridge configuration
|
46
46
|
|
47
47
|
List of arguments
|
48
48
|
-l|--rhlogin rhlogin Red Hat login (RHN or OpenShift login) (#{rhlogin})
|
@@ -63,7 +63,7 @@ List of arguments
|
|
63
63
|
--alias alias Specify server alias (when using add/remove-alias)
|
64
64
|
--config path Path of alternate config file
|
65
65
|
--timeout # Timeout, in seconds, for the session
|
66
|
-
--enable-jenkins [name]
|
66
|
+
--enable-jenkins [name] Enables builds for your application with Jenkins. You may optionally specify the name of the Jenkins application that is created (default: 'jenkins'). Note that --no-dns is ignored for the creation of the Jenkins application.
|
67
67
|
USAGE
|
68
68
|
exit exit_code
|
69
69
|
end
|
@@ -180,7 +180,7 @@ currently being created: '#{$opt['app']}'
|
|
180
180
|
puts "
|
181
181
|
Found a bug? Post to the forum and we'll get right on it.
|
182
182
|
IRC: #openshift on freenode
|
183
|
-
Forums: https://
|
183
|
+
Forums: https://openshift.redhat.com/community/forums/openshift
|
184
184
|
|
185
185
|
"
|
186
186
|
end
|
@@ -365,7 +365,10 @@ def show_embedded_list
|
|
365
365
|
type_keys = RHC::get_cartridge_listing(nil, ', ', libra_server, RHC::Config.default_proxy, 'embedded', false)
|
366
366
|
puts type_keys
|
367
367
|
puts ""
|
368
|
-
|
368
|
+
|
369
|
+
# we should always get something back unless there was an error
|
370
|
+
exit 255 if type_keys.length == 0
|
371
|
+
exit 0
|
369
372
|
end
|
370
373
|
|
371
374
|
def save_or_restore_snapshot(command)
|
data/bin/rhc-chk
CHANGED
@@ -105,7 +105,7 @@ end
|
|
105
105
|
$debuginfo = {
|
106
106
|
'environment' => {
|
107
107
|
'Ruby Version' => RUBY_VERSION,
|
108
|
-
"host_alias" => Config::CONFIG['host_alias']
|
108
|
+
"host_alias" => (Object.const_get(defined?(RbConfig) ? :RbConfig : :Config))::CONFIG['host_alias'],
|
109
109
|
},
|
110
110
|
'options' => {
|
111
111
|
"Command Line" => $opt,
|
@@ -197,10 +197,11 @@ def error_for(name,*args)
|
|
197
197
|
if name.kind_of? String
|
198
198
|
name = name.downcase.to_sym
|
199
199
|
end
|
200
|
-
|
200
|
+
|
201
|
+
message = sprintf(get_message(:errors,name),*(args.shift || ''))
|
201
202
|
solution = get_message(:solutions,name)
|
202
203
|
if solution
|
203
|
-
message << "\n" << sprintf(solution,*args)
|
204
|
+
message << "\n" << sprintf(solution,*(args.shift || ''))
|
204
205
|
end
|
205
206
|
message
|
206
207
|
end
|
@@ -213,6 +214,43 @@ def get_message(type,name)
|
|
213
214
|
val
|
214
215
|
end
|
215
216
|
|
217
|
+
# This test tries to make sure we have the keys unlocked before testing
|
218
|
+
# to ensure nicer workflow
|
219
|
+
class Test0_SSH_Keys_Unlocked < Test::Unit::TestCase
|
220
|
+
include TestBase
|
221
|
+
|
222
|
+
def test_ssh_quick
|
223
|
+
begin
|
224
|
+
# Get user info from OpenShift
|
225
|
+
data = {'rhlogin' => $rhlogin}
|
226
|
+
response = fetch_url_json("/broker/userinfo", data)
|
227
|
+
resp_json = RHC::json_decode(response.body)
|
228
|
+
user_info = RHC::json_decode(resp_json['data'].to_s)
|
229
|
+
|
230
|
+
# Get any keys Net::SSH thinks we'll need
|
231
|
+
$ssh = Net::SSH
|
232
|
+
needed_keys =
|
233
|
+
user_info['app_info'].map do |name,opts|
|
234
|
+
host = "%s-%s.%s" % [
|
235
|
+
name,
|
236
|
+
user_info['user_info']['namespace'],
|
237
|
+
user_info['user_info']['rhc_domain']
|
238
|
+
]
|
239
|
+
$ssh.configuration_for(host)[:keys].map{|f| File.expand_path(f)}
|
240
|
+
end.compact.flatten
|
241
|
+
|
242
|
+
agent_keys = Net::SSH::Authentication::Agent.connect.identities.map{|x| x.comment }
|
243
|
+
missing_keys = needed_keys - agent_keys
|
244
|
+
|
245
|
+
unless missing_keys.empty?
|
246
|
+
$stderr.puts "\n NOTE: These tests may require you to unlock one or more of your SSH keys \n\n"
|
247
|
+
end
|
248
|
+
rescue
|
249
|
+
end
|
250
|
+
end
|
251
|
+
|
252
|
+
end
|
253
|
+
|
216
254
|
class Test1_Connectivity < Test::Unit::TestCase
|
217
255
|
include TestBase
|
218
256
|
def teardown
|
@@ -265,8 +303,6 @@ end
|
|
265
303
|
#
|
266
304
|
class Test3_SSH < Test::Unit::TestCase
|
267
305
|
|
268
|
-
@@local_derived_ssh_pubkey = nil
|
269
|
-
@@local_ssh_pubkey = nil
|
270
306
|
|
271
307
|
include TestBase
|
272
308
|
|
@@ -277,64 +313,94 @@ class Test3_SSH < Test::Unit::TestCase
|
|
277
313
|
end
|
278
314
|
end
|
279
315
|
|
280
|
-
def
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
# Derive the public key from the private key
|
285
|
-
key_dump = RHC::Vendor::SSHKey.new(File.read(@libra_kfile)).ssh_public_key
|
286
|
-
@@local_derived_ssh_pubkey = key_dump.to_s.strip.split(' ')[1]
|
316
|
+
def require_login(test)
|
317
|
+
flunk(error_for(:no_account,test)) if $user_info.nil?
|
318
|
+
end
|
287
319
|
|
288
|
-
|
289
|
-
|
320
|
+
def require_remote_keys(test)
|
321
|
+
require_login(test)
|
322
|
+
@@remote_pub_keys ||= (
|
290
323
|
|
291
324
|
ssh_keys = RHC::get_ssh_keys($libra_server, $rhlogin, $password, $http)
|
292
325
|
my_keys = [ssh_keys['ssh_key'], ssh_keys['keys'].values.map{|k| k['key']}].flatten
|
293
326
|
my_keys.delete_if{|x| x.length == 0 }
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
assert(!$remote_ssh_pubkeys.empty?, error_for(:no_remote_pub_keys ) )
|
298
|
-
assert $remote_ssh_pubkeys.include?(@@local_derived_ssh_pubkey), error_for(:no_match_pub, @libra_kfile)
|
327
|
+
my_keys
|
328
|
+
)
|
329
|
+
flunk(error_for(:no_remote_pub_keys,test)) if @@remote_pub_keys.nil?
|
299
330
|
end
|
300
331
|
|
301
|
-
def
|
302
|
-
|
332
|
+
def require_agent_keys(fatal = true)
|
333
|
+
@@agent_keys ||= (
|
334
|
+
begin
|
335
|
+
Net::SSH::Authentication::Agent.connect.identities
|
336
|
+
rescue
|
337
|
+
nil
|
338
|
+
end
|
339
|
+
)
|
340
|
+
flunk(error_for(:no_keys_loaded)) if (fatal && @@agent_keys.nil?)
|
341
|
+
end
|
303
342
|
|
304
|
-
|
305
|
-
|
306
|
-
|
343
|
+
def agent_key_names
|
344
|
+
@@agent_keys.map{|x| File.expand_path(x.comment) }
|
345
|
+
end
|
307
346
|
|
308
|
-
|
347
|
+
def agent_key_fingerprints
|
348
|
+
@@agent_keys.map{|x| x.to_s.split("\n")[1..-2].join('') }
|
349
|
+
end
|
309
350
|
|
310
|
-
|
311
|
-
|
312
|
-
|
351
|
+
def libra_public_key
|
352
|
+
@@local_ssh_pubkey ||= (
|
353
|
+
fp = File.open(@libra_kpfile)
|
354
|
+
fp.gets.split(' ')[1]
|
355
|
+
)
|
313
356
|
ensure
|
314
357
|
fp.close if fp
|
315
358
|
end
|
316
359
|
|
317
|
-
def
|
318
|
-
|
319
|
-
|
320
|
-
|
321
|
-
|
322
|
-
|
360
|
+
def test_01_local_files
|
361
|
+
[
|
362
|
+
[@libra_kfile, /[4-7]00/], # Needs to at least be readable by user and nobody else
|
363
|
+
[@libra_kpfile, /.../], # Any permissions are OK
|
364
|
+
].each do |args|
|
365
|
+
continue_test{check_permissions(*args)}
|
366
|
+
end
|
367
|
+
end
|
368
|
+
|
369
|
+
def test_02_ssh_agent
|
370
|
+
require_agent_keys
|
323
371
|
|
324
|
-
|
325
|
-
assert loaded_keys.include?(@@local_ssh_pubkey),error_for(:pubkey_not_loaded)
|
372
|
+
assert agent_key_names.include?(File.expand_path(@libra_kfile)) ,error_for(:pubkey_not_loaded, ": #{@libra_kpfile}")
|
326
373
|
end
|
327
374
|
|
328
|
-
def
|
329
|
-
|
330
|
-
|
375
|
+
def test_03_remote_ssh_keys
|
376
|
+
require_remote_keys("whether you have a valid key loaded in your agent")
|
377
|
+
require_agent_keys(false)
|
378
|
+
|
379
|
+
assert !(@@remote_pub_keys & [agent_key_fingerprints,libra_public_key].flatten).empty? ,error_for(:pubkey_not_loaded," ")
|
380
|
+
end
|
381
|
+
|
382
|
+
def test_04_ssh_connect
|
383
|
+
require_login("connecting to your applications")
|
384
|
+
|
385
|
+
host_template = "%%s-%s.%s" % [
|
386
|
+
$user_info['user_info']['domains'][0]['namespace'],
|
387
|
+
$user_info['user_info']['rhc_domain']
|
388
|
+
]
|
331
389
|
$user_info['app_info'].each do |k,v|
|
332
390
|
uuid = v['uuid']
|
333
|
-
|
334
|
-
|
335
|
-
|
336
|
-
|
337
|
-
|
391
|
+
hostname = host_template % k
|
392
|
+
timeout = 10
|
393
|
+
begin
|
394
|
+
@ssh = Net::SSH.start(hostname,uuid,{:timeout => timeout})
|
395
|
+
rescue Timeout::Error
|
396
|
+
if timeout < 30
|
397
|
+
timeout += 10
|
398
|
+
retry
|
399
|
+
end
|
400
|
+
ensure
|
401
|
+
continue_test{ assert_not_nil @ssh, error_for(:cant_ssh, hostname) }
|
402
|
+
@ssh.close if @ssh
|
403
|
+
end
|
338
404
|
end
|
339
405
|
end
|
340
406
|
|
@@ -346,7 +412,7 @@ class Test3_SSH < Test::Unit::TestCase
|
|
346
412
|
|
347
413
|
perms = sprintf('%o',File.stat(file).mode)[-3..-1]
|
348
414
|
|
349
|
-
assert_match permission, perms, error_for(:bad_permissions,file,perms,permission.source)
|
415
|
+
assert_match permission, perms, error_for(:bad_permissions,[file,perms],permission.source)
|
350
416
|
end
|
351
417
|
end
|
352
418
|
|
@@ -460,7 +526,7 @@ $messages = YAML.load <<-EOF
|
|
460
526
|
:errors:
|
461
527
|
:no_derive: "We were unable to derive your public SSH key and compare it to the remote"
|
462
528
|
:no_connectivity: "Cannot connect to server, therefore most tests will not work"
|
463
|
-
:no_account: You must have an account on the server in order to test
|
529
|
+
:no_account: "You must have an account on the server in order to test: %s"
|
464
530
|
:cant_connect: You need to be able to connect to the server in order to test authentication
|
465
531
|
:no_match_pub: "Local %s does not match remote pub key, SSH auth will not work"
|
466
532
|
:_404: "The user %s does not have an account on this server"
|
@@ -470,9 +536,9 @@ $messages = YAML.load <<-EOF
|
|
470
536
|
:_other_http: "There was an error communicating with the server: %s"
|
471
537
|
:bad_permissions: "File %s has incorrect permissions %s"
|
472
538
|
:no_keys_loaded: Either ssh-agent is not running or you do not have any keys loaded
|
473
|
-
:pubkey_not_loaded: Your public key is not loaded into a running ssh-agent
|
539
|
+
:pubkey_not_loaded: "Your public key is not loaded into a running ssh-agent%s"
|
474
540
|
:cant_ssh: "Cannot SSH into your app: %s"
|
475
|
-
:no_remote_pub_keys: "
|
541
|
+
:no_remote_pub_keys: "You do not have any public keys associated with your OpenShift account. Cannot test: %s"
|
476
542
|
:solutions:
|
477
543
|
:no_connectivity: "Ensure that you are able to connect to %s"
|
478
544
|
:no_match_pub: "Perhaps you should regenerate your public key, or run 'rhc sshkey add' to add your new key"
|
@@ -480,4 +546,6 @@ $messages = YAML.load <<-EOF
|
|
480
546
|
:_401: "Please ensure you used the correct password"
|
481
547
|
:bad_permissions: "Permissions should match %s"
|
482
548
|
:no_remote_pub_keys: "You should try to add your ssh-key by running 'rhc sshkey add'"
|
549
|
+
:pubkey_not_loaded: If this is your only error, your connection may still work, depending on your SSH configuration
|
550
|
+
:no_keys_loaded: If this is your only error, your connection may still work, depending on your SSH configuration
|
483
551
|
EOF
|
data/bin/rhc-create-app
CHANGED
@@ -179,7 +179,7 @@ if @mydebug
|
|
179
179
|
puts "
|
180
180
|
Found a bug? Post to the forum and we'll get right on it.
|
181
181
|
IRC: #openshift on freenode
|
182
|
-
Forums: https://
|
182
|
+
Forums: https://openshift.redhat.com/community/forums/openshift
|
183
183
|
|
184
184
|
"
|
185
185
|
end
|
data/bin/rhc-create-domain
CHANGED
@@ -91,19 +91,6 @@ if !password
|
|
91
91
|
password = RHC::get_password
|
92
92
|
end
|
93
93
|
|
94
|
-
#
|
95
|
-
# Add a new namespace to configs
|
96
|
-
#
|
97
|
-
def add_rhlogin_config(rhlogin, uuid)
|
98
|
-
f = open(File.expand_path(config_path), 'a')
|
99
|
-
unless config.get_value('default_rhlogin')
|
100
|
-
f.puts("# Default rhlogin to use if none is specified")
|
101
|
-
f.puts("default_rhlogin=#{rhlogin}")
|
102
|
-
f.puts("")
|
103
|
-
end
|
104
|
-
f.close
|
105
|
-
end
|
106
|
-
|
107
94
|
#
|
108
95
|
# Check to see if a ssh_key_file_path exists, if not create it.
|
109
96
|
#
|
@@ -143,8 +130,6 @@ if response.code == '200'
|
|
143
130
|
begin
|
144
131
|
json_resp = RHC::json_decode(response.body)
|
145
132
|
RHC::print_response_success(json_resp)
|
146
|
-
json_rhlogininfo = RHC::json_decode(json_resp['data'])
|
147
|
-
add_rhlogin_config(json_rhlogininfo['rhlogin'], json_rhlogininfo['uuid'])
|
148
133
|
if opt['alter'] != ''
|
149
134
|
puts <<EOF
|
150
135
|
Creation successful
|