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.
- data/bin/rhc +7 -49
- data/bin/rhc-app +14 -3
- data/bin/rhc-chk +16 -16
- data/bin/rhc-create-app +2 -0
- data/bin/rhc-create-domain +1 -2
- data/bin/rhc-ctl-app +12 -3
- data/bin/rhc-ctl-domain +1 -2
- data/bin/rhc-domain +1 -2
- data/bin/rhc-domain-info +1 -2
- data/bin/rhc-port-forward +1 -2
- data/bin/rhc-snapshot +3 -0
- data/bin/rhc-sshkey +1 -2
- data/bin/rhc-tail-files +1 -1
- data/bin/rhc-user-info +1 -3
- data/features/application.feature +4 -1
- data/features/domain.feature +0 -4
- data/features/geared_application.feature +11 -0
- data/features/lib/rhc_helper/app.rb +16 -5
- data/features/lib/rhc_helper/cartridge.rb +25 -9
- data/features/lib/rhc_helper/commandify.rb +34 -7
- data/features/lib/rhc_helper/domain.rb +2 -2
- data/features/lib/rhc_helper/httpify.rb +24 -14
- data/features/lib/rhc_helper/persistable.rb +1 -1
- data/features/lib/rhc_helper/sshkey.rb +11 -7
- data/features/lib/rhc_helper.rb +5 -3
- data/features/multiple_cartridge.feature +1 -1
- data/features/scaled_application.feature +48 -0
- data/features/sshkey.feature +37 -31
- data/features/step_definitions/application_steps.rb +18 -7
- data/features/step_definitions/cartridge_steps.rb +29 -3
- data/features/step_definitions/domain_steps.rb +2 -2
- data/features/step_definitions/sshkey_steps.rb +34 -34
- data/features/support/assumptions.rb +21 -9
- data/features/support/before_hooks.rb +24 -6
- data/features/support/env.rb +45 -19
- data/lib/rhc/cartridge_helper.rb +27 -0
- data/lib/rhc/cli.rb +1 -1
- data/lib/rhc/command_runner.rb +31 -3
- data/lib/rhc/commands/alias.rb +38 -0
- data/lib/rhc/commands/app.rb +478 -0
- data/lib/rhc/commands/base.rb +42 -12
- data/lib/rhc/commands/cartridge.rb +189 -0
- data/lib/rhc/commands/domain.rb +11 -49
- data/lib/rhc/commands/port-forward.rb +0 -1
- data/lib/rhc/commands/setup.rb +2 -1
- data/lib/rhc/commands/snapshot.rb +118 -0
- data/lib/rhc/commands/sshkey.rb +24 -38
- data/lib/rhc/commands/tail.rb +24 -0
- data/lib/rhc/commands/threaddump.rb +16 -0
- data/lib/rhc/commands.rb +33 -7
- data/lib/rhc/config.rb +28 -12
- data/lib/rhc/context_helper.rb +19 -5
- data/lib/rhc/core_ext.rb +86 -0
- data/lib/rhc/exceptions.rb +44 -0
- data/lib/rhc/git_helper.rb +59 -0
- data/lib/rhc/helpers.rb +86 -5
- data/lib/rhc/output_helpers.rb +213 -0
- data/lib/rhc/rest/application.rb +134 -67
- data/lib/rhc/rest/base.rb +48 -0
- data/lib/rhc/rest/cartridge.rb +40 -44
- data/lib/rhc/rest/client.rb +127 -59
- data/lib/rhc/rest/domain.rb +29 -39
- data/lib/rhc/rest/gear_group.rb +10 -0
- data/lib/rhc/rest/key.rb +8 -23
- data/lib/rhc/rest/user.rb +8 -24
- data/lib/rhc/rest.rb +22 -11
- data/lib/rhc/ssh_key_helpers.rb +47 -0
- data/lib/rhc/usage_templates/help.erb +0 -1
- data/lib/rhc/version.rb +3 -3
- data/lib/rhc/wizard.rb +123 -225
- data/lib/rhc-common.rb +43 -62
- data/spec/rest_spec_helper.rb +159 -36
- data/spec/rhc/cli_spec.rb +29 -1
- data/spec/rhc/command_spec.rb +32 -35
- data/spec/rhc/commands/alias_spec.rb +123 -0
- data/spec/rhc/commands/app_spec.rb +414 -0
- data/spec/rhc/commands/cartridge_spec.rb +342 -0
- data/spec/rhc/commands/domain_spec.rb +8 -8
- data/spec/rhc/commands/setup_spec.rb +17 -6
- data/spec/rhc/commands/snapshot_spec.rb +140 -0
- data/spec/rhc/commands/sshkey_spec.rb +26 -4
- data/spec/rhc/commands/tail_spec.rb +34 -0
- data/spec/rhc/commands/threaddump_spec.rb +83 -0
- data/spec/rhc/config_spec.rb +39 -13
- data/spec/rhc/context_spec.rb +51 -0
- data/spec/rhc/helpers_spec.rb +52 -12
- data/spec/rhc/rest_application_spec.rb +16 -3
- data/spec/rhc/rest_client_spec.rb +144 -36
- data/spec/rhc/rest_spec.rb +1 -1
- data/spec/rhc/wizard_spec.rb +133 -232
- data/spec/spec_helper.rb +4 -3
- metadata +56 -31
- data/features/support/ssh.sh +0 -2
- data/spec/rhc/common_spec.rb +0 -49
@@ -0,0 +1,24 @@
|
|
1
|
+
require 'rhc/commands/base'
|
2
|
+
require 'rhc/config'
|
3
|
+
require 'rhc-common'
|
4
|
+
module RHC::Commands
|
5
|
+
class Tail < Base
|
6
|
+
summary "Tail the logs of an application"
|
7
|
+
syntax "<application>"
|
8
|
+
argument :app, "Name of application you wish to view the logs of", ["-a", "--app app"]
|
9
|
+
option ["-n", "--namespace namespace"], "Namespace of your application", :context => :namespace_context, :required => true
|
10
|
+
option ["-o", "--opts options"], "Options to pass to the server-side (linux based) tail command (applicable to tail command only) (-f is implicit. See the linux tail man page full list of options.) (Ex: --opts '-n 100')"
|
11
|
+
option ["-f", "--files files"], "File glob relative to app (default <application_name>/logs/*) (optional)"
|
12
|
+
alias_action :"app tail", :root_command => true, :deprecated => true
|
13
|
+
def run(app)
|
14
|
+
begin
|
15
|
+
rest_domain = rest_client.find_domain(options.namespace)
|
16
|
+
rest_app = rest_domain.find_application(app)
|
17
|
+
rest_app.tail(options)
|
18
|
+
rescue Interrupt
|
19
|
+
results { say "Terminating..." }
|
20
|
+
end
|
21
|
+
0
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'rhc/commands/base'
|
2
|
+
module RHC::Commands
|
3
|
+
class Threaddump < Base
|
4
|
+
summary "Trigger a thread dump for JBoss and Ruby applications."
|
5
|
+
syntax "<application>"
|
6
|
+
option ["-n", "--namespace namespace"], "Namespace of your application", :context => :namespace_context, :required => true
|
7
|
+
argument :app, "Name of the application on which to execute the thread dump", ["-a", "--app name"]
|
8
|
+
def run(app)
|
9
|
+
rest_domain = rest_client.find_domain(options.namespace)
|
10
|
+
rest_app = rest_domain.find_application(app)
|
11
|
+
rest_app.threaddump.messages.each { |m| say m }
|
12
|
+
|
13
|
+
0
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
data/lib/rhc/commands.rb
CHANGED
@@ -1,6 +1,32 @@
|
|
1
1
|
require 'commander'
|
2
2
|
require 'rhc/helpers'
|
3
3
|
|
4
|
+
## monkey patch option parsing to also parse global options all at once
|
5
|
+
# to avoid conflicts and side effects of similar short switches
|
6
|
+
module Commander
|
7
|
+
class Command
|
8
|
+
def parse_options_and_call_procs *args
|
9
|
+
return args if args.empty?
|
10
|
+
opts = OptionParser.new
|
11
|
+
runner = Commander::Runner.instance
|
12
|
+
# add global options
|
13
|
+
runner.options.each do |option|
|
14
|
+
opts.on *option[:args],
|
15
|
+
&runner.global_option_proc(option[:switches], &option[:proc])
|
16
|
+
|
17
|
+
end
|
18
|
+
|
19
|
+
# add command options
|
20
|
+
@options.each do |option|
|
21
|
+
opts.on(*option[:args], &option[:proc])
|
22
|
+
opts
|
23
|
+
end
|
24
|
+
|
25
|
+
opts.parse! args
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
4
30
|
module RHC
|
5
31
|
module Commands
|
6
32
|
def self.load
|
@@ -27,12 +53,10 @@ module RHC
|
|
27
53
|
command_name = Commander::Runner.instance.command_name_from_args
|
28
54
|
command = Commander::Runner.instance.active_command
|
29
55
|
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
warn "Warning: #{msg} For porting and testing purposes you may switch this warning to an error by setting the DISABLE_DEPRECATED environment variable to 1. This command may be removed in future releases."
|
56
|
+
new_cmd = deprecated[command_name.to_sym]
|
57
|
+
if new_cmd
|
58
|
+
new_cmd = "rhc #{command.name}" if new_cmd == true
|
59
|
+
RHC::Helpers.deprecated_command new_cmd
|
36
60
|
end
|
37
61
|
end
|
38
62
|
|
@@ -64,6 +88,8 @@ module RHC
|
|
64
88
|
o[:arg] = Commander::Runner.switch_to_sym(o[:switches].last)
|
65
89
|
end
|
66
90
|
|
91
|
+
deprecated[name.to_sym] = opts[:deprecated] unless opts[:deprecated].nil?
|
92
|
+
|
67
93
|
args_metadata = opts[:args] || []
|
68
94
|
args_metadata.each do |arg_meta|
|
69
95
|
arg_switches = arg_meta[:switches]
|
@@ -81,7 +107,7 @@ module RHC
|
|
81
107
|
# prepend the current resource
|
82
108
|
alias_components = name.split(" ")
|
83
109
|
alias_components[-1] = a[:action]
|
84
|
-
alias_cmd = alias_components.join(' ')
|
110
|
+
alias_cmd = alias_components.join(' ').to_sym
|
85
111
|
end
|
86
112
|
|
87
113
|
deprecated[alias_cmd] = true if a[:deprecated]
|
data/lib/rhc/config.rb
CHANGED
@@ -116,6 +116,10 @@ module RHC
|
|
116
116
|
def opts_login=(username)
|
117
117
|
@opts.add('default_rhlogin', username)
|
118
118
|
end
|
119
|
+
|
120
|
+
def opts_login
|
121
|
+
@opts['default_rhlogin']
|
122
|
+
end
|
119
123
|
|
120
124
|
# password is not allowed in config files and can only be passed on comman line
|
121
125
|
def password=(password)
|
@@ -170,6 +174,10 @@ module RHC
|
|
170
174
|
def has_opts_config?
|
171
175
|
!@opts_config.nil?
|
172
176
|
end
|
177
|
+
|
178
|
+
def has_opts?
|
179
|
+
!@opts.nil?
|
180
|
+
end
|
173
181
|
|
174
182
|
def should_run_ssh_wizard?
|
175
183
|
not File.exists? @ssh_priv_key_file_path
|
@@ -206,21 +214,29 @@ module RHC
|
|
206
214
|
end
|
207
215
|
|
208
216
|
def default_proxy
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
if ENV['http_proxy']!~/^(\w+):\/\// then
|
215
|
-
ENV['http_proxy']="http://" + ENV['http_proxy']
|
217
|
+
@default_proxy ||= (
|
218
|
+
proxy = ENV['http_proxy'] || ENV['HTTP_PROXY']
|
219
|
+
if proxy
|
220
|
+
if proxy !~ /^(\w+):\/\// then
|
221
|
+
proxy = "http://#{proxy}"
|
216
222
|
end
|
217
|
-
|
218
|
-
|
223
|
+
ENV['http_proxy'] = proxy
|
224
|
+
proxy_uri = URI.parse(ENV['http_proxy'])
|
225
|
+
Net::HTTP::Proxy(proxy_uri.host, proxy_uri.port, proxy_uri.user, proxy_uri.password)
|
219
226
|
else
|
220
|
-
|
227
|
+
Net::HTTP
|
221
228
|
end
|
222
|
-
|
223
|
-
|
229
|
+
)
|
230
|
+
end
|
231
|
+
|
232
|
+
def using_proxy?
|
233
|
+
default_proxy.instance_variable_get(:@is_proxy_class) || false
|
234
|
+
end
|
235
|
+
|
236
|
+
def proxy_vars
|
237
|
+
Hash[[:address,:user,:pass,:port].map do |x|
|
238
|
+
[x,default_proxy.instance_variable_get("@proxy_#{x}")]
|
239
|
+
end]
|
224
240
|
end
|
225
241
|
end
|
226
242
|
end
|
data/lib/rhc/context_helper.rb
CHANGED
@@ -1,17 +1,31 @@
|
|
1
|
+
require 'rhc/git_helper'
|
2
|
+
|
1
3
|
module RHC
|
2
4
|
module ContextHelpers
|
5
|
+
include RHC::GitHelpers
|
6
|
+
|
3
7
|
def app_context
|
4
|
-
|
5
|
-
|
6
|
-
|
8
|
+
debug "Getting app context"
|
9
|
+
|
10
|
+
uuid = git_config_get "rhc.app-uuid"
|
11
|
+
|
12
|
+
# proof of concept - we shouldn't be traversing
|
13
|
+
# the broker should expose apis for getting the application via a uuid
|
14
|
+
rest_client.domains.each do |rest_domain|
|
15
|
+
rest_domain.applications.each do |rest_app|
|
16
|
+
return rest_app.name if rest_app.uuid == uuid
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
debug "Couldn't find app with UUID == #{uuid}"
|
7
21
|
nil
|
8
22
|
end
|
9
23
|
|
10
24
|
def namespace_context
|
11
25
|
# right now we don't have any logic since we only support one domain
|
12
|
-
# :
|
26
|
+
# TODO: add domain lookup based on uuid
|
13
27
|
domain = rest_client.domains[0]
|
14
|
-
raise RHC::DomainNotFoundException
|
28
|
+
raise RHC::DomainNotFoundException, "No domains configured for this user. You may create one using 'rhc domain create'." if domain.nil?
|
15
29
|
|
16
30
|
domain.id
|
17
31
|
end
|
data/lib/rhc/core_ext.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
# From Rails core_ext/object.rb
|
2
2
|
require 'rhc/json'
|
3
3
|
require 'open-uri'
|
4
|
+
require 'highline'
|
4
5
|
|
5
6
|
class Object
|
6
7
|
def present?
|
@@ -24,6 +25,15 @@ class File
|
|
24
25
|
end
|
25
26
|
end
|
26
27
|
|
28
|
+
class String
|
29
|
+
# Wrap string by the given length, and join it with the given character.
|
30
|
+
# The method doesn't distinguish between words, it will only work based on
|
31
|
+
# the length.
|
32
|
+
def wrap(wrap_length=80, char="\n")
|
33
|
+
scan(/.{#{wrap_length}}|.+/).join(char)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
27
37
|
#
|
28
38
|
# Allow http => https redirection, see
|
29
39
|
# http://bugs.ruby-lang.org/issues/859 to 1.8.7 for rough
|
@@ -38,3 +48,79 @@ module OpenURI
|
|
38
48
|
(/\A(?:http|ftp)\z/i =~ uri1.scheme && /\A(?:https?|ftp)\z/i =~ uri2.scheme)
|
39
49
|
end
|
40
50
|
end
|
51
|
+
|
52
|
+
# Some versions of highline get in an infinite loop when trying to wrap.
|
53
|
+
# Fixes BZ 866530.
|
54
|
+
class HighLine
|
55
|
+
|
56
|
+
def wrap_line(line)
|
57
|
+
wrapped_line = []
|
58
|
+
i = chars_in_line = 0
|
59
|
+
word = []
|
60
|
+
|
61
|
+
while i < line.length
|
62
|
+
# we have to give a length to the index because ruby 1.8 returns the
|
63
|
+
# byte code when using a single fixednum index
|
64
|
+
c = line[i, 1]
|
65
|
+
color_code = nil
|
66
|
+
# escape character probably means color code, let's check
|
67
|
+
if c == "\e"
|
68
|
+
color_code = line[i..i+6].match(/\e\[\d{1,2}m/)
|
69
|
+
if color_code
|
70
|
+
# first the existing word buffer then the color code
|
71
|
+
wrapped_line << word.join.wrap(@wrap_at) << color_code[0]
|
72
|
+
word.clear
|
73
|
+
|
74
|
+
i += color_code[0].length
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
# visible character
|
79
|
+
if !color_code
|
80
|
+
chars_in_line += 1
|
81
|
+
word << c
|
82
|
+
|
83
|
+
# time to wrap the line?
|
84
|
+
if chars_in_line == @wrap_at
|
85
|
+
if c == ' ' or line[i+1, 1] == ' ' or word.length == @wrap_at
|
86
|
+
wrapped_line << word.join
|
87
|
+
word.clear
|
88
|
+
end
|
89
|
+
|
90
|
+
wrapped_line[-1].rstrip!
|
91
|
+
wrapped_line << "\n"
|
92
|
+
|
93
|
+
# consume any spaces at the begining of the next line
|
94
|
+
word = word.join.lstrip.split(//)
|
95
|
+
chars_in_line = word.length
|
96
|
+
|
97
|
+
if line[i+1, 1] == ' '
|
98
|
+
i += 1 while line[i+1, 1] == ' '
|
99
|
+
end
|
100
|
+
|
101
|
+
else
|
102
|
+
if c == ' '
|
103
|
+
wrapped_line << word.join
|
104
|
+
word.clear
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
i += 1
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
wrapped_line << word.join
|
113
|
+
wrapped_line.join
|
114
|
+
end
|
115
|
+
|
116
|
+
def wrap(text)
|
117
|
+
wrapped_text = []
|
118
|
+
lines = text.split(/\r?\n/)
|
119
|
+
lines.each_with_index do |line, i|
|
120
|
+
wrapped_text << wrap_line(i == lines.length - 1 ? line : line.rstrip)
|
121
|
+
end
|
122
|
+
|
123
|
+
return wrapped_text.join("\n")
|
124
|
+
end
|
125
|
+
|
126
|
+
end
|
data/lib/rhc/exceptions.rb
CHANGED
@@ -19,12 +19,32 @@ module RHC
|
|
19
19
|
end
|
20
20
|
end
|
21
21
|
|
22
|
+
class CartridgeNotFoundException < Exception
|
23
|
+
def initialize(message="Cartridge not found")
|
24
|
+
super message, 154
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
class MultipleCartridgesException < Exception
|
29
|
+
def initialize(message="Multiple cartridge found")
|
30
|
+
super message, 155
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
22
34
|
class KeyNotFoundException < Exception
|
23
35
|
def initialize(message="SSHKey not found")
|
24
36
|
super message, 118
|
25
37
|
end
|
26
38
|
end
|
27
39
|
|
40
|
+
# Makes sense to use its own exit code since this is different from a
|
41
|
+
# resource error
|
42
|
+
class GitException < Exception
|
43
|
+
def initialize(message="Git returned an error")
|
44
|
+
super message, 216
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
28
48
|
class DeprecatedError < RuntimeError; end
|
29
49
|
|
30
50
|
class KeyFileNotExistentException < Exception
|
@@ -68,4 +88,28 @@ module RHC
|
|
68
88
|
super message, 1
|
69
89
|
end
|
70
90
|
end
|
91
|
+
|
92
|
+
class SnapshotSaveException < Exception
|
93
|
+
def initialize(message="Error trying to save snapshot")
|
94
|
+
super message, 130
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
class SnapshotRestoreException < Exception
|
99
|
+
def initialize(message="Error trying to restore snapshot")
|
100
|
+
super message, 130
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
class MissingScalingValueException < Exception
|
105
|
+
def initialize(message="Must provide either a min or max value for scaling")
|
106
|
+
super message, 1
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
class CartridgeNotScalableException < Exception
|
111
|
+
def initialize(message="Cartridge is not scalable")
|
112
|
+
super message, 1
|
113
|
+
end
|
114
|
+
end
|
71
115
|
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
require 'open4'
|
2
|
+
|
3
|
+
module RHC
|
4
|
+
module GitHelpers
|
5
|
+
# :nocov: These all call external binaries so test them in cucumber
|
6
|
+
def git_config_get(key)
|
7
|
+
config_get_cmd = "git config --get #{key}"
|
8
|
+
debug "Running #{config_get_cmd}"
|
9
|
+
uuid = %x[#{config_get_cmd}].strip
|
10
|
+
debug "UUID = '#{uuid}'"
|
11
|
+
uuid = nil if $?.exitstatus != 0 or uuid.empty?
|
12
|
+
|
13
|
+
uuid
|
14
|
+
end
|
15
|
+
|
16
|
+
def git_config_set(key, value)
|
17
|
+
unset_cmd = "git config --unset-all #{key}"
|
18
|
+
config_cmd = "git config --add #{key} #{value}"
|
19
|
+
debug "Adding #{key} = #{value} to git config"
|
20
|
+
commands = [unset_cmd, config_cmd]
|
21
|
+
commands.each do |cmd|
|
22
|
+
debug "Running #{cmd} 2>&1"
|
23
|
+
output = %x[#{cmd} 2>&1]
|
24
|
+
raise RHC::GitException, "Error while adding config values to git - #{output}" unless output.empty?
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def git_clone_repo(git_url, repo_dir)
|
29
|
+
# quote the repo to avoid input injection risk
|
30
|
+
repo_dir = (repo_dir ? " \"#{repo_dir}\"" : "")
|
31
|
+
clone_cmd = "git clone #{git_url}#{repo_dir}"
|
32
|
+
debug "Running #{clone_cmd}"
|
33
|
+
|
34
|
+
err = nil
|
35
|
+
if RHC::Helpers.windows?
|
36
|
+
# windows does not support Open4 so redirect stderr to stdin
|
37
|
+
# and print the whole output which is not as clean
|
38
|
+
output = %x[#{clone_cmd} 2>&1]
|
39
|
+
if $?.exitstatus != 0
|
40
|
+
err = output + " - Check to make sure you have correctly installed git and it is added to your path."
|
41
|
+
else
|
42
|
+
say output
|
43
|
+
end
|
44
|
+
else
|
45
|
+
paragraph do
|
46
|
+
Open4.popen4(clone_cmd) do |pid, stdin, stdout, stderr|
|
47
|
+
stdin.close
|
48
|
+
say stdout.read
|
49
|
+
err = stderr.read
|
50
|
+
end
|
51
|
+
say "done"
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
raise RHC::GitException, "Error in git clone - #{err}" if $?.exitstatus != 0
|
56
|
+
end
|
57
|
+
# :nocov:
|
58
|
+
end
|
59
|
+
end
|
data/lib/rhc/helpers.rb
CHANGED
@@ -1,6 +1,8 @@
|
|
1
1
|
require 'commander/user_interaction'
|
2
|
+
require 'rhc/version'
|
2
3
|
require 'rhc/config'
|
3
4
|
require 'rhc/commands'
|
5
|
+
require 'rhc/output_helpers'
|
4
6
|
|
5
7
|
OptionParser.accept(URI) {|s,| URI.parse(s) if s}
|
6
8
|
|
@@ -18,9 +20,13 @@ module RHC
|
|
18
20
|
# helpers always have Commander UI available
|
19
21
|
include Commander::UI
|
20
22
|
include Commander::UI::AskForClass
|
23
|
+
include RHC::OutputHelpers
|
21
24
|
|
22
25
|
extend self
|
23
26
|
|
27
|
+
MAX_RETRIES = 7
|
28
|
+
DEFAULT_DELAY_THROTTLE = 2.0
|
29
|
+
|
24
30
|
def disable_deprecated?
|
25
31
|
# 1) default for now is false
|
26
32
|
# 2) when releasing a 1.0 beta flip this to true
|
@@ -74,7 +80,7 @@ module RHC
|
|
74
80
|
global_option '-p', '--password password', "OpenShift password"
|
75
81
|
global_option '-d', '--debug', "Turn on debugging"
|
76
82
|
|
77
|
-
global_option '--noprompt', "
|
83
|
+
global_option '--noprompt', "Suppress the interactive setup wizard from running before a command"
|
78
84
|
global_option '--config FILE', "Path of a different config file"
|
79
85
|
def config
|
80
86
|
raise "Operations requiring configuration must define a config accessor"
|
@@ -94,6 +100,29 @@ module RHC
|
|
94
100
|
# Output helpers
|
95
101
|
#
|
96
102
|
|
103
|
+
def debug(msg)
|
104
|
+
$stderr.puts "DEBUG: #{msg}" if debug?
|
105
|
+
end
|
106
|
+
|
107
|
+
def deprecated_command(correct,short = false)
|
108
|
+
deprecated("This command is deprecated. Please use '#{correct}' instead.",short)
|
109
|
+
end
|
110
|
+
|
111
|
+
def deprecated_option(deprecated,new)
|
112
|
+
deprecated("The option '#{deprecated}' is deprecated. Please use '#{new}' instead")
|
113
|
+
end
|
114
|
+
|
115
|
+
def deprecated(msg,short = false)
|
116
|
+
info = " For porting and testing purposes you may switch this %s to %s by setting the DISABLE_DEPRECATED environment variable to %d. It is not recommended to do so in a production environment as this option may be removed in future releases."
|
117
|
+
|
118
|
+
msg << info unless short
|
119
|
+
if RHC::Helpers.disable_deprecated?
|
120
|
+
raise DeprecatedError.new(msg % ['an error','a warning',0])
|
121
|
+
else
|
122
|
+
warn "Warning: #{msg}\n" % ['a warning','an error',1]
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
97
126
|
def say(msg)
|
98
127
|
super
|
99
128
|
msg
|
@@ -132,12 +161,54 @@ module RHC
|
|
132
161
|
end
|
133
162
|
end
|
134
163
|
|
135
|
-
|
136
|
-
|
137
|
-
|
164
|
+
# This will format table headings for a consistent look and feel
|
165
|
+
# If a heading isn't explicitly defined, it will attempt to look up the parts
|
166
|
+
# If those aren't found, it will capitalize the string
|
167
|
+
def table_heading(value)
|
168
|
+
# Set the default proc to look up undefined values
|
169
|
+
headings = Hash.new do |hash,key|
|
170
|
+
items = key.to_s.split('_')
|
171
|
+
# Look up each piece individually
|
172
|
+
hash[key] = items.length > 1 ?
|
173
|
+
# Recusively look up the heading for the parts
|
174
|
+
items.map{|x| headings[x.to_sym]}.join(' ') :
|
175
|
+
# Capitalize if this part isn't defined
|
176
|
+
items.first.capitalize
|
177
|
+
end
|
178
|
+
|
179
|
+
# Predefined headings (or parts of headings)
|
180
|
+
headings.merge!({
|
181
|
+
:creation_time => "Created",
|
182
|
+
:uuid => "UUID",
|
183
|
+
:current_scale => "Current",
|
184
|
+
:scales_from => "Minimum",
|
185
|
+
:scales_to => "Maximum",
|
186
|
+
:url => "URL",
|
187
|
+
:ssh => "SSH",
|
188
|
+
:gear_profile => "Gear Size"
|
189
|
+
})
|
190
|
+
|
191
|
+
headings[value]
|
192
|
+
end
|
193
|
+
|
194
|
+
def header(s,opts = {})
|
195
|
+
@indent ||= 0
|
196
|
+
indent s
|
197
|
+
indent "="*s.length
|
198
|
+
if block_given?
|
199
|
+
@indent += 1
|
200
|
+
yield
|
201
|
+
@indent -= 1
|
202
|
+
end
|
138
203
|
end
|
139
204
|
|
140
|
-
|
205
|
+
INDENT = 2
|
206
|
+
def indent(str)
|
207
|
+
@indent ||= 0
|
208
|
+
say "%s%s" % [" " * @indent * INDENT,str]
|
209
|
+
end
|
210
|
+
|
211
|
+
##
|
141
212
|
# section
|
142
213
|
#
|
143
214
|
# highline helper mixin which correctly formats block of say and ask
|
@@ -225,5 +296,15 @@ module RHC
|
|
225
296
|
def windows? ; RUBY_PLATFORM =~ /win(32|dows|ce)|djgpp|(ms|cyg|bcc)win|mingw32/i end
|
226
297
|
def unix? ; !jruby? && !windows? end
|
227
298
|
|
299
|
+
# common SSH key display format in ERB
|
300
|
+
def ssh_key_display_format
|
301
|
+
ERB.new <<-FORMAT
|
302
|
+
Name: <%= key.name %>
|
303
|
+
Type: <%= key.type %>
|
304
|
+
Fingerprint: <%= key.fingerprint %>
|
305
|
+
|
306
|
+
FORMAT
|
307
|
+
end
|
308
|
+
|
228
309
|
end
|
229
310
|
end
|