rhc 0.81.14 → 0.82.18
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.
- data/Rakefile +15 -3
- data/bin/rhc-chk +356 -124
- data/bin/rhc-create-app +21 -23
- data/bin/rhc-ctl-app +13 -8
- data/lib/rhc-common.rb +65 -47
- metadata +10 -10
data/Rakefile
CHANGED
@@ -3,7 +3,13 @@
|
|
3
3
|
require 'rubygems'
|
4
4
|
require 'rake'
|
5
5
|
require 'rake/clean'
|
6
|
-
|
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
|
-
|
35
|
-
|
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
|
data/bin/rhc-chk
CHANGED
@@ -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
|
-
|
35
|
-
|
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
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
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
|
-
|
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
|
-
|
75
|
-
|
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
|
-
|
95
|
+
if $opt["debug"]
|
96
|
+
$debug = true
|
83
97
|
end
|
84
|
-
RHC::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
|
-
|
102
|
+
$opt["rhlogin"] = get_var('default_rhlogin') unless $opt["rhlogin"]
|
103
|
+
if !RHC::check_rhlogin($opt['rhlogin'])
|
104
|
+
p_usage
|
91
105
|
end
|
92
|
-
|
106
|
+
$rhlogin = $opt["rhlogin"]
|
93
107
|
|
94
|
-
|
95
|
-
if
|
96
|
-
|
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
|
-
|
103
|
-
|
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
|
-
|
110
|
-
|
111
|
-
|
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
|
-
|
114
|
-
|
148
|
+
$http = Net::HTTP
|
149
|
+
$debuginfo['environment']['proxy'] = "none"
|
115
150
|
end
|
116
151
|
|
117
|
-
|
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://#{
|
120
|
-
|
121
|
-
|
122
|
-
|
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
|
-
|
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
|
-
|
131
|
-
|
132
|
-
|
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
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
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
|
-
|
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
|
262
|
+
# Checking ssh key
|
160
263
|
#
|
161
|
-
|
162
|
-
puts "TEST1: Confirming connection to OpenShift"
|
163
|
-
data = {'cart_type' => 'standalone'}
|
264
|
+
class Test3_SSH < Test::Unit::TestCase
|
164
265
|
|
165
|
-
|
166
|
-
|
266
|
+
@@local_derived_ssh_pubkey = nil
|
267
|
+
@@local_ssh_pubkey = nil
|
167
268
|
|
269
|
+
include TestBase
|
168
270
|
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
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
|
-
|
177
|
-
@
|
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
|
-
|
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
|
-
|
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
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
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
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
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
|
-
|
221
|
-
|
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
|
-
|
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
|
data/bin/rhc-create-app
CHANGED
@@ -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
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
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
|
-
|
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
|
-
|
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
|
data/bin/rhc-ctl-app
CHANGED
@@ -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
|
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
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
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
|
|
data/lib/rhc-common.rb
CHANGED
@@ -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
|
-
|
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
|
-
|
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,
|
357
|
-
puts "
|
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
|
-
|
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
|
476
|
-
|
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
|
-
|
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
|
529
|
-
|
530
|
-
|
531
|
-
|
532
|
-
|
533
|
-
|
534
|
-
|
535
|
-
|
536
|
-
|
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
|
-
|
614
|
-
|
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
|
-
|
666
|
-
|
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:
|
4
|
+
hash: 371
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 0
|
8
|
-
-
|
9
|
-
-
|
10
|
-
version: 0.
|
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-
|
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.
|
104
|
+
rubygems_version: 1.8.11
|
105
105
|
signing_key:
|
106
106
|
specification_version: 3
|
107
107
|
summary: OpenShift Express Client Tools
|