rhc 1.7.8 → 1.8.9

Sign up to get free protection for your applications and to get access to all the features.
Files changed (39) hide show
  1. data/autocomplete/rhc_bash +3 -3
  2. data/features/lib/rhc_helper/commandify.rb +1 -1
  3. data/features/lib/rhc_helper/loggable.rb +2 -2
  4. data/features/support/before_hooks.rb +19 -4
  5. data/features/support/env.rb +3 -3
  6. data/lib/rhc/cartridge_helpers.rb +9 -3
  7. data/lib/rhc/commands.rb +1 -0
  8. data/lib/rhc/commands/app.rb +35 -19
  9. data/lib/rhc/commands/apps.rb +2 -2
  10. data/lib/rhc/commands/authorization.rb +2 -2
  11. data/lib/rhc/commands/cartridge.rb +9 -5
  12. data/lib/rhc/commands/domain.rb +7 -9
  13. data/lib/rhc/commands/port_forward.rb +6 -5
  14. data/lib/rhc/commands/tail.rb +5 -3
  15. data/lib/rhc/context_helper.rb +1 -1
  16. data/lib/rhc/exceptions.rb +12 -0
  17. data/lib/rhc/helpers.rb +18 -4
  18. data/lib/rhc/highline_extensions.rb +11 -4
  19. data/lib/rhc/rest/application.rb +22 -10
  20. data/lib/rhc/rest/attributes.rb +5 -0
  21. data/lib/rhc/rest/cartridge.rb +32 -2
  22. data/lib/rhc/rest/domain.rb +7 -1
  23. data/lib/rhc/rest/gear_group.rb +1 -1
  24. data/lib/rhc/rest/mock.rb +20 -5
  25. data/lib/rhc/wizard.rb +4 -4
  26. data/spec/rhc/auth_spec.rb +2 -0
  27. data/spec/rhc/command_spec.rb +3 -1
  28. data/spec/rhc/commands/app_spec.rb +19 -1
  29. data/spec/rhc/commands/apps_spec.rb +2 -2
  30. data/spec/rhc/commands/domain_spec.rb +5 -5
  31. data/spec/rhc/commands/port_forward_spec.rb +40 -0
  32. data/spec/rhc/commands/server_spec.rb +13 -8
  33. data/spec/rhc/commands/tail_spec.rb +29 -0
  34. data/spec/rhc/highline_extensions_spec.rb +15 -0
  35. data/spec/rhc/rest_application_spec.rb +41 -9
  36. data/spec/rhc/rest_spec.rb +12 -1
  37. data/spec/rhc/wizard_spec.rb +19 -2
  38. data/spec/wizard_spec_helper.rb +3 -3
  39. metadata +347 -342
@@ -174,7 +174,7 @@ _rhc()
174
174
 
175
175
  "rhc app create")
176
176
  if [[ "$cur" == -* ]]; then
177
- opts="--app --dns --enable-jenkins --from-code --gear-size --git --namespace --no-dns --no-git --nogit --repo --scaling --type"
177
+ opts="--app --dns --enable-jenkins --from-code --gear-size --git --namespace --no-dns --no-git --no-keys --nogit --repo --scaling --type"
178
178
  else
179
179
  opts=""
180
180
  fi
@@ -262,7 +262,7 @@ _rhc()
262
262
 
263
263
  "rhc app-create")
264
264
  if [[ "$cur" == -* ]]; then
265
- opts="--app --dns --enable-jenkins --from-code --gear-size --git --namespace --no-dns --no-git --nogit --repo --scaling --type"
265
+ opts="--app --dns --enable-jenkins --from-code --gear-size --git --namespace --no-dns --no-git --no-keys --nogit --repo --scaling --type"
266
266
  else
267
267
  opts=""
268
268
  fi
@@ -614,7 +614,7 @@ _rhc()
614
614
 
615
615
  "rhc create-app")
616
616
  if [[ "$cur" == -* ]]; then
617
- opts="--app --dns --enable-jenkins --from-code --gear-size --git --namespace --no-dns --no-git --nogit --repo --scaling --type"
617
+ opts="--app --dns --enable-jenkins --from-code --gear-size --git --namespace --no-dns --no-git --no-keys --nogit --repo --scaling --type"
618
618
  else
619
619
  opts=""
620
620
  fi
@@ -93,7 +93,7 @@ module RHCHelper
93
93
  args << arg0.first if arg0.first
94
94
  end
95
95
 
96
- args.rstrip
96
+ args.rstrip.gsub(/([\\\$])/, "\\\\\\1")
97
97
  end
98
98
 
99
99
  # This looks for a callback method that is defined for the command.
@@ -19,10 +19,10 @@ module RHCHelper
19
19
  original_formatter = Logger::Formatter.new
20
20
  @logger.formatter = proc { |severity, datetime, progname, msg|
21
21
  # Filter out any passwords
22
- filter_msg = msg.gsub(PASSWORD_REGEX, " -p ***** ")
22
+ #filter_msg = msg.gsub(PASSWORD_REGEX, " -p ***** ")
23
23
 
24
24
  # Format with the original formatter
25
- original_formatter.call(severity, datetime, progname, filter_msg)
25
+ original_formatter.call(severity, datetime, progname, msg)
26
26
  }
27
27
  end
28
28
 
@@ -1,7 +1,3 @@
1
- Before('@clean') do
2
- clean_applications(true)
3
- end
4
-
5
1
  Before('@sshkey') do
6
2
  Sshkey.remove "key1"
7
3
  Sshkey.remove "key2"
@@ -16,12 +12,22 @@ Before('@geared_user_required') do
16
12
  $old_username = $username
17
13
  $username = "user_with_multiple_gear_sizes@test.com"
18
14
  $namespace = nil
15
+
16
+ if !$cleaned_gears
17
+ clean_applications($username)
18
+ $cleaned_gears = true
19
+ end
19
20
  end
20
21
 
21
22
  Before('@certificates_capable_user_required') do
22
23
  $old_username = $username
23
24
  $username = "user_with_certificate_capabilities@test.com"
24
25
  $namespace = nil
26
+
27
+ if !$cleaned_certificates
28
+ clean_applications($username)
29
+ $cleaned_certificates = true
30
+ end
25
31
  end
26
32
 
27
33
  After do
@@ -37,6 +43,15 @@ Before('@cartridge_storage_user_required') do
37
43
  $old_username = $username
38
44
  $username = "user_with_extra_storage@test.com"
39
45
  $namespace = nil
46
+
47
+ if !$cleaned_storage
48
+ clean_applications($username)
49
+ $cleaned_storage = true
50
+ end
51
+ end
52
+
53
+ Before('@clean') do
54
+ clean_applications($username, true)
40
55
  end
41
56
 
42
57
  Before('@domain_required') do
@@ -105,9 +105,9 @@ _log " Creating New Namespace: #{$namespace.nil?}"
105
105
  _log "--------------------------------------------------------------------------------------------------"
106
106
  _log "\n\n"
107
107
 
108
- def clean_applications(leave_domain = false)
108
+ def clean_applications(user=$username,leave_domain=false)
109
109
  return if ENV['NO_CLEAN']
110
- users = [$username,'user_with_multiple_gear_sizes@test.com','user_with_extra_storage@test.com']
110
+ users = Array(user)
111
111
 
112
112
  _log " Cleaning up test applications..."
113
113
 
@@ -128,8 +128,8 @@ def clean_applications(leave_domain = false)
128
128
  app.delete
129
129
  end
130
130
  end
131
- domain.delete unless leave_domain
132
131
  end
132
+ client.domains.each{ |domain| domain.delete } unless leave_domain
133
133
  client.sshkeys.each do |key|
134
134
  _log "\t\tKey: #{key.name}"
135
135
  key.delete
@@ -7,6 +7,8 @@ module RHC
7
7
  from = opts[:from] || all_cartridges
8
8
 
9
9
  cartridge_names.map do |name|
10
+ next use_cart(RHC::Rest::Cartridge.for_url(name), name) if name =~ %r(\Ahttps?://)i
11
+
10
12
  name = name.downcase
11
13
  from.find{ |c| c.name.downcase == name } ||
12
14
  begin
@@ -33,7 +35,11 @@ module RHC
33
35
  end
34
36
 
35
37
  def use_cart(cart, for_cartridge_name)
36
- info "Using #{cart.name}#{cart.display_name ? " (#{cart.display_name})" : ''} for '#{for_cartridge_name}'"
38
+ if cart.custom?
39
+ info "The cartridge '#{cart.url}' will be downloaded and installed"
40
+ else
41
+ info "Using #{cart.name}#{cart.display_name ? " (#{cart.display_name})" : ''} for '#{for_cartridge_name}'"
42
+ end
37
43
  cart
38
44
  end
39
45
 
@@ -50,7 +56,7 @@ module RHC
50
56
  lambda{ |cart|
51
57
  next cart unless cart.is_a? Array
52
58
  name = cart.instance_variable_get(:@for)
53
- matching = cart.select(&:only_in_new?)
59
+ matching = cart.select{ |c| not c.only_in_existing? }
54
60
  if matching.empty?
55
61
  raise RHC::MultipleCartridgesException, "You must select only a single web cartridge. '#{name}' matches web cartridges."
56
62
  elsif matching.size == 1
@@ -93,6 +99,6 @@ module RHC
93
99
  carts.unshift ['==========', '=========']
94
100
  carts.unshift ['Short Name', 'Full name']
95
101
  say table(carts)
96
- end
102
+ end
97
103
  end
98
104
  end
@@ -299,6 +299,7 @@ module RHC
299
299
  raise ArgumentError, "Missing required argument '#{arg[:name]}'." unless arg[:optional]
300
300
  break if available.empty?
301
301
  else
302
+ value = Array(value) if arg[:arg_type] == :list
302
303
  slots[i] = value
303
304
  options.__hash__[option] = value if option
304
305
  end
@@ -6,7 +6,12 @@ require 'rhc/cartridge_helpers'
6
6
  module RHC::Commands
7
7
  class App < Base
8
8
  summary "Commands for creating and managing applications"
9
- description "Creates and controls an OpenShift application. To see the list of all applications use the rhc domain show command. Note that delete is not reversible and will stop your application and then remove the application and repo from the remote server. No local changes are made."
9
+ description <<-DESC
10
+ Creates and controls an OpenShift application. To see the list of all
11
+ applications use the rhc domain show command. Note that delete is not
12
+ reversible and will stop your application and then remove the application
13
+ and repo from the remote server. No local changes are made.
14
+ DESC
10
15
  syntax "<action>"
11
16
  default_action :help
12
17
  suppress_wizard
@@ -19,7 +24,11 @@ module RHC::Commands
19
24
  scheduled jobs, or continuous integration.
20
25
 
21
26
  You can see a list of all valid cartridge types by running
22
- 'rhc cartridge list'.
27
+ 'rhc cartridge list'. OpenShift also supports downloading cartridges -
28
+ pass a URL in place of the cartridge name and we'll download
29
+ and install that cartridge into your app. Keep in mind that
30
+ these cartridges receive no security updates. Note that not
31
+ all OpenShift servers allow downloaded cartridges.
23
32
 
24
33
  When your application is created, a domain name that is a combination
25
34
  of the name of your app and the namespace of your domain will be
@@ -38,7 +47,7 @@ module RHC::Commands
38
47
  may be specified to change the gears used.
39
48
 
40
49
  DESC
41
- syntax "<name> <cartridge> [-n namespace]"
50
+ syntax "<name> <cartridge> [... <cartridge>] [-n namespace]"
42
51
  option ["-n", "--namespace NAME"], "Namespace for the application"
43
52
  option ["-g", "--gear-size SIZE"], "Gear size controls how much memory and CPU your cartridges can use."
44
53
  option ["-s", "--scaling"], "Enable scaling for the web cartridge."
@@ -51,7 +60,6 @@ module RHC::Commands
51
60
  option ["--enable-jenkins [NAME]"], "Enable Jenkins builds for this application (will create a Jenkins application if not already available). The default name will be 'jenkins' if not specified."
52
61
  argument :name, "Name for your application", ["-a", "--app NAME"], :optional => true
53
62
  argument :cartridges, "The web framework this application should use", ["-t", "--type CARTRIDGE"], :optional => true, :arg_type => :list
54
- #argument :additional_cartridges, "A list of other cartridges such as databases you wish to add. Cartridges can also be added later using 'rhc cartridge add'", [], :arg_type => :list
55
63
  def create(name, cartridges)
56
64
  check_config!
57
65
 
@@ -69,7 +77,7 @@ module RHC::Commands
69
77
  rest_app = nil
70
78
 
71
79
  cart_names = cartridges.collect do |c|
72
- c.usage_rate? ? "#{c.name} (addtl. costs may apply)" : c.name
80
+ c.usage_rate? ? "#{c.short_name} (addtl. costs may apply)" : c.short_name
73
81
  end.join(', ')
74
82
 
75
83
  paragraph do
@@ -88,13 +96,9 @@ module RHC::Commands
88
96
  paragraph do
89
97
  say "Creating application '#{name}' ... "
90
98
 
91
-
92
99
  # create the main app
93
- rest_app = create_app(name, cartridges.map(&:name), rest_domain,
94
- options.gear_size, options.scaling, options.from_code)
95
-
100
+ rest_app = create_app(name, cartridges, rest_domain, options.gear_size, options.scaling, options.from_code)
96
101
  messages.concat(rest_app.messages)
97
-
98
102
  success "done"
99
103
  end
100
104
 
@@ -115,8 +119,8 @@ module RHC::Commands
115
119
  warn "not complete"
116
120
  add_issue("Jenkins failed to install - #{e}",
117
121
  "Installing jenkins and jenkins-client",
118
- "rhc app create jenkins",
119
- "rhc cartridge add jenkins-client -a #{rest_app.name}")
122
+ "rhc create-app jenkins",
123
+ "rhc add-cartridge jenkins-client -a #{rest_app.name}")
120
124
  end
121
125
  end
122
126
  end
@@ -276,7 +280,19 @@ module RHC::Commands
276
280
  say "Cartridge #{gg.cartridges.collect { |c| c['name'] }.join(', ')} is #{gear_group_state(gg.gears.map{ |g| g['state'] })}"
277
281
  end
278
282
  elsif options.gears
279
- say table(gear_groups_for_app(app_name).map{ |gg| gg.gears.map{ |g| [g['id'], g['state'], gg.cartridges.map{ |c| c['name'] }.join(", ")] } }.flatten(1))
283
+ gear_info = gear_groups_for_app(app_name).map do |group|
284
+ group.gears.map do |gear|
285
+ [
286
+ gear['id'],
287
+ gear['state'] == 'started' ? gear['state'] : color(gear['state'], :yellow),
288
+ group.cartridges.collect{ |c| c['name'] }.join(' '),
289
+ group.gear_profile,
290
+ ssh_string(gear['ssh_url'])
291
+ ]
292
+ end
293
+ end.flatten(1)
294
+
295
+ say table(gear_info, :header => ['ID', 'State', 'Cartridges', 'Size', 'SSH URL'])
280
296
  else
281
297
  app = rest_client.find_application(options.namespace, app_name, :include => :cartridges)
282
298
  display_app(app, app.cartridges)
@@ -325,8 +341,8 @@ module RHC::Commands
325
341
  def require_one_web_cart
326
342
  lambda{ |carts|
327
343
  match, ambiguous = carts.partition{ |c| not c.is_a?(Array) }
328
- selected_web = match.any?(&:only_in_new?)
329
- possible_web = ambiguous.flatten.any?(&:only_in_new?)
344
+ selected_web = match.any?{ |c| not c.only_in_existing? }
345
+ possible_web = ambiguous.flatten.any?{ |c| not c.only_in_existing? }
330
346
  if not (selected_web or possible_web)
331
347
  section(:bottom => 1){ list_cartridges(standalone_cartridges) }
332
348
  raise RHC::CartridgeNotFoundException, "Every application needs a web cartridge to handle incoming web requests. Please provide the short name of one of the carts listed above."
@@ -363,11 +379,11 @@ module RHC::Commands
363
379
  rest_client.find_domain(options.namespace)
364
380
  else
365
381
  if rest_client.domains.empty?
366
- raise RHC::Rest::DomainNotFoundException, "No domains found. Please create a domain with 'rhc domain create <namespace>' before creating applications." unless interactive?
382
+ raise RHC::Rest::DomainNotFoundException, "No domains found. Please create a domain with 'rhc create-domain <namespace>' before creating applications." unless interactive?
367
383
  RHC::DomainWizard.new(config, options, rest_client).run
368
384
  end
369
385
  domain = rest_client.domains.first
370
- raise RHC::Rest::DomainNotFoundException, "No domains found. Please create a domain with 'rhc domain create <namespace>' before creating applications." unless domain
386
+ raise RHC::Rest::DomainNotFoundException, "No domains found. Please create a domain with 'rhc create-domain <namespace>' before creating applications." unless domain
371
387
  options.namespace = domain.id
372
388
  domain
373
389
  end
@@ -446,7 +462,7 @@ module RHC::Commands
446
462
  warn "not complete"
447
463
  add_issue("Jenkins client failed to install - #{exit_message}",
448
464
  "Install the jenkins client",
449
- "rhc cartridge add jenkins-client -a #{rest_app.name}")
465
+ "rhc add-cartridge jenkins-client -a #{rest_app.name}")
450
466
  end
451
467
  end
452
468
 
@@ -565,7 +581,7 @@ WARNING: Your application was created successfully but had problems during
565
581
  If this doesn't work for you, let us know in the forums or in IRC and we'll
566
582
  make sure to get you up and running.
567
583
 
568
- Forums - https://openshift.redhat.com/community/forums/openshift
584
+ Forums - https://www.openshift.com/forums/openshift
569
585
  IRC - #openshift (on Freenode)
570
586
 
571
587
  !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
@@ -7,12 +7,12 @@ module RHC::Commands
7
7
  def run
8
8
  domains = rest_client.domains
9
9
 
10
- info "In order to deploy applications, you must create a domain with 'rhc setup' or 'rhc domain create'." and return 1 if domains.empty?
10
+ info "In order to deploy applications, you must create a domain with 'rhc setup' or 'rhc create-domain'." and return 1 if domains.empty?
11
11
 
12
12
  applications = domains.map{ |d| d.applications(:include => :cartridges) }.flatten.sort
13
13
 
14
14
  applications.each{ |a| display_app(a, a.cartridges) }.blank? and
15
- info "No applications. Use 'rhc app create'." and
15
+ info "No applications. Use 'rhc create-app'." and
16
16
  return 1
17
17
 
18
18
  success "You have #{applications.length} applications"
@@ -7,7 +7,7 @@ module RHC::Commands
7
7
  can add, edit, or delete authorizations with subcommands.
8
8
 
9
9
  An authorization token grants access to the OpenShift REST API with
10
- a set of privleges called 'scopes' for a limited time. You can
10
+ a set of privileges called 'scopes' for a limited time. You can
11
11
  add an optional note to each authorization token to assist you in
12
12
  remembering what is available.
13
13
  DESC
@@ -25,7 +25,7 @@ module RHC::Commands
25
25
  syntax "--scopes SCOPES [--note NOTE] [--expires-in SECONDS]"
26
26
  description <<-DESC
27
27
  Add an authorization to your account. An authorization token grants
28
- access to the OpenShift REST API with a set of privleges called 'scopes'
28
+ access to the OpenShift REST API with a set of privileges called 'scopes'
29
29
  for a limited time. You can add an optional note to each authorization
30
30
  token to assist you in remembering what is available.
31
31
 
@@ -17,7 +17,11 @@ module RHC::Commands
17
17
  (like Jenkins) or provide environment variables.
18
18
 
19
19
  Use the 'cartridges' command to see a list of all available cartridges.
20
- Add a new cartridge to your application with 'add-cartridge'.
20
+ Add a new cartridge to your application with 'add-cartridge'. OpenShift
21
+ also supports downloading cartridges - pass a URL in place of the cartridge
22
+ name and we'll download and install that cartridge into your app. Keep
23
+ in mind that these cartridges receive no security updates. Note that
24
+ not all OpenShift servers allow downloaded cartridges.
21
25
 
22
26
  For scalable applications, use the 'cartridge-scale' command on the web
23
27
  cartridge to set the minimum and maximum scale.
@@ -42,7 +46,7 @@ module RHC::Commands
42
46
  paragraph do
43
47
  name = c.display_name != c.name && "#{color(c.display_name, :cyan)} [#{c.name}]" || c.name
44
48
  tags = c.tags - RHC::Rest::Cartridge::HIDDEN_TAGS
45
- say header([name, "(#{c.only_in_new? ? 'web' : 'addon'})"])
49
+ say header([name, "(#{c.only_in_existing? ? 'addon' : 'web'})"])
46
50
  say c.description
47
51
  paragraph{ say "Tagged with: #{tags.sort.join(', ')}" } if tags.present?
48
52
  paragraph{ say format_usage_message(c) } if c.usage_rate?
@@ -52,7 +56,7 @@ module RHC::Commands
52
56
  say table(carts.collect do |c|
53
57
  [c.usage_rate? ? "#{c.name} (*)" : c.name,
54
58
  c.display_name,
55
- c.only_in_new? ? 'web' : 'addon']
59
+ c.only_in_existing? ? 'addon' : 'web']
56
60
  end)
57
61
  end
58
62
 
@@ -71,12 +75,12 @@ module RHC::Commands
71
75
  def add(cart_type)
72
76
  cart = check_cartridges(cart_type, :from => not_standalone_cartridges).first
73
77
 
74
- say "Adding #{cart.name} to application '#{options.app}' ... "
78
+ say "Adding #{cart.short_name} to application '#{options.app}' ... "
75
79
 
76
80
  say format_usage_message(cart) if cart.usage_rate?
77
81
 
78
82
  rest_app = rest_client.find_application(options.namespace, options.app, :include => :cartridges)
79
- rest_cartridge = rest_app.add_cartridge(cart.name)
83
+ rest_cartridge = rest_app.add_cartridge(cart)
80
84
 
81
85
  success "Success"
82
86
 
@@ -26,7 +26,7 @@ module RHC::Commands
26
26
 
27
27
  results do
28
28
  say "Success!"
29
- say "You may now create an application using the 'rhc app create' command"
29
+ say "You may now create an application using the 'rhc create-app' command"
30
30
  end
31
31
 
32
32
  0
@@ -40,14 +40,12 @@ module RHC::Commands
40
40
  def update(old_namespace, new_namespace)
41
41
  domain = rest_client.find_domain(old_namespace)
42
42
 
43
- say "Changing namespace '#{domain.id}' to '#{new_namespace}'..."
43
+ say "Changing namespace '#{domain.id}' to '#{new_namespace}' ... "
44
44
 
45
45
  domain.update(new_namespace)
46
46
 
47
- results do
48
- say "Success!"
49
- say "You can use 'rhc domain show' to view any url changes. Be sure to update any links including the url in your local git config: <local_git_repo>/.git/config"
50
- end
47
+ success "success"
48
+ info "Applications in this domain will use the new namespace in their URL."
51
49
 
52
50
  0
53
51
  end
@@ -56,7 +54,7 @@ module RHC::Commands
56
54
  def show
57
55
  domain = rest_client.domains.first
58
56
 
59
- warn "In order to deploy applications, you must create a domain with 'rhc setup' or 'rhc domain create'." and return 1 unless domain
57
+ warn "In order to deploy applications, you must create a domain with 'rhc setup' or 'rhc create-domain'." and return 1 unless domain
60
58
 
61
59
  applications = domain.applications(:include => :cartridges)
62
60
 
@@ -68,7 +66,7 @@ module RHC::Commands
68
66
  end
69
67
  success "You have #{applications.length} applications in your domain."
70
68
  else
71
- success "The domain #{domain.id} exists but has no applications. You can use 'rhc app create' to create a new application."
69
+ success "The domain #{domain.id} exists but has no applications. You can use 'rhc create-app' to create a new application."
72
70
  end
73
71
 
74
72
  0
@@ -94,7 +92,7 @@ module RHC::Commands
94
92
  begin
95
93
  domain.destroy
96
94
  rescue RHC::Rest::ClientErrorException #FIXME: I am insufficiently specific
97
- raise RHC::Exception.new("Domain contains applications. Delete applications first.", 128)
95
+ raise RHC::Exception.new("Your domain contains applications. Delete applications first.", 128)
98
96
  end
99
97
 
100
98
  success "deleted"
@@ -72,11 +72,12 @@ module RHC::Commands
72
72
  syntax "<application>"
73
73
  option ["-n", "--namespace NAME"], "Namespace of the application you are port forwarding to", :context => :namespace_context, :required => true
74
74
  argument :app, "Application you are port forwarding to (required)", ["-a", "--app NAME"]
75
+ option ["-g", "--gear ID"], "Gear ID you are port forwarding to (optional)"
75
76
  def run(app)
76
77
  rest_app = rest_client.find_application(options.namespace, app)
78
+ ssh_uri = URI.parse(options.gear ? rest_app.gear_ssh_url(options.gear) : rest_app.ssh_url)
77
79
 
78
- ssh_uri = URI.parse(rest_app.ssh_url)
79
- say "Using #{rest_app.ssh_url}..." if options.debug
80
+ say "Using #{ssh_uri}..." if options.debug
80
81
 
81
82
  forwarding_specs = []
82
83
 
@@ -104,7 +105,7 @@ module RHC::Commands
104
105
  end
105
106
  end
106
107
  end
107
-
108
+
108
109
  if forwarding_specs.length == 0
109
110
  # check if the gears have been stopped
110
111
  ggs = rest_app.gear_groups
@@ -115,7 +116,7 @@ module RHC::Commands
115
116
  warn "Application #{rest_app.name} is stopped. Please restart the application and try again."
116
117
  return 1
117
118
  else
118
- raise RHC::NoPortsToForwardException.new "There are no available ports to forward for this application. Your application may be stopped."
119
+ raise RHC::NoPortsToForwardException.new "There are no available ports to forward for this application. Your application may be stopped or idled."
119
120
  end
120
121
  end
121
122
 
@@ -148,7 +149,7 @@ module RHC::Commands
148
149
  say table(
149
150
  bound_ports.map do |fs|
150
151
  [fs.service, "#{fs.host_from}:#{fs.port_from}", " => ", "#{fs.remote_host}:#{fs.port_to.to_s}"]
151
- end,
152
+ end,
152
153
  :header => ["Service", "Local", " ", "OpenShift"]
153
154
  )
154
155
  end