Class: RHC::Commands::PortForward
- Defined in:
- lib/rhc/commands/port_forward.rb
Constant Summary collapse
- UP_TO_256 =
/25[0-5]|2[0-4][0-9]|[01]?(?:[0-9][0-9]?)/
- UP_TO_65535 =
/6553[0-5]|655[0-2][0-9]|65[0-4][0-9][0-9]|6[0-4][0-9][0-9][0-9]|[0-5]?(?:[0-9][0-9]{0,3})/
- HOST_AND_PORT =
‘host’ part is a bit lax; we rely on ‘rhc-list-ports’ to hand us a reasonable output about the host information, be it numeric or FQDN in IPv4 or IPv6.
/(.+):(#{UP_TO_65535})\b/
Constants included from Helpers
Helpers::BOUND_WARNING, Helpers::PREFIX, Helpers::ROLES
Instance Method Summary collapse
Methods inherited from Base
Methods included from RHC::ContextHelpers
#find_app, #find_domain, #find_membership_container, #find_team, #from_local_git, included, #namespace_context, #server_context
Methods included from GitHelpers
#git_clone_application, #git_clone_deploy_hooks, #git_clone_repo, #git_cmd, #git_config_get, #git_config_set, #git_remote_add, #git_version, #has_git?
Methods included from Helpers
#agree, #certificate_file, #client_from_options, #collect_env_vars, #color, #confirm_action, #date, #datetime_rfc3339, #debug, #debug?, #debug_error, #decode_json, #deprecated, #deprecated_command, #disable_deprecated?, #distance_of_time_in_words, #env_var_regex_pattern, #error, #exec, #host_exists?, #hosts_file_contains?, #human_size, #info, #interactive?, #jruby?, #mac?, #openshift_online_server?, #openshift_rest_endpoint, #openshift_server, #openshift_url, #pluralize, #results, #role_name, #run_with_tee, #ssh_string, #ssh_string_parts, #ssl_options, #success, #system_path, #table_heading, #to_host, #to_uri, #token_for_user, #unix?, #user_agent, #warn, #windows?, #with_tolerant_encoding
Methods included from OutputHelpers
#default_display_env_var, #display_app, #display_app_configurations, #display_authorization, #display_cart, #display_cart_storage_info, #display_cart_storage_list, #display_deployment, #display_deployment_list, #display_domain, #display_env_var_list, #display_key, #display_team, #format_cart_gears, #format_cart_header, #format_gear_info, #format_key_header, #format_scaling_info, #format_usage_message
Constructor Details
This class inherits a constructor from RHC::Commands::Base
Instance Method Details
#run(app) ⇒ Object
74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 |
# File 'lib/rhc/commands/port_forward.rb', line 74 def run(app) rest_app = find_app ssh_uri = URI.parse(.gear ? rest_app.gear_ssh_url(.gear) : rest_app.ssh_url) say "Using #{ssh_uri}..." if .debug forwarding_specs = [] begin say "Checking available ports ... " Net::SSH.start(ssh_uri.host, ssh_uri.user) do |ssh| # If a specific gear is targeted, do not include remote (e.g. database) ports list_ports_cmd = "rhc-list-ports#{.gear ? ' --exclude-remote' : ''}" ssh.exec! list_ports_cmd do |channel, stream, data| if stream == :stderr data.each_line do |line| line.chomp! # FIXME: This is really brittle; there must be a better way # for the server to tell us that permission (what permission?) # is denied. raise RHC::PermissionDeniedException.new "Permission denied." if line =~ /permission denied/i # ...and also which services are available for the application # for us to forward ports for. if line =~ /\A\s*(\S+) -> #{HOST_AND_PORT}\z/ debug fs = ForwardingSpec.new($1, $2, $3.to_i) forwarding_specs << fs else debug line end end end end if forwarding_specs.length == 0 # check if the gears have been stopped if rest_app.gear_groups.all?{ |gg| gg.gears.all?{ |g| g["state"] == "stopped" } } warn "none" error "The application is stopped. Please restart the application and try again." return 1 else warn "none" raise RHC::NoPortsToForwardException.new "There are no available ports to forward for this application. Your application may be stopped or idled." end end success "done" begin Net::SSH.start(ssh_uri.host, ssh_uri.user) do |ssh| say "Forwarding ports ..." forwarding_specs.each do |fs| given_up = nil while !fs.bound? && !given_up begin args = fs.to_fwd_args debug args.inspect ssh.forward.local(*args) fs.bound = true rescue Errno::EADDRINUSE, Errno::EACCES => e warn "#{e} while forwarding port #{fs.port_from}. Trying local port #{fs.port_from+1}" fs.port_from += 1 rescue Timeout::Error, Errno::EADDRNOTAVAIL, Errno::EHOSTUNREACH, Errno::ECONNREFUSED, Net::SSH::AuthenticationFailed => e given_up = true end end end bound_ports = forwarding_specs.select(&:bound?) if bound_ports.length > 0 paragraph{ say "To connect to a service running on OpenShift, use the Local address" } paragraph do say table( bound_ports.map do |fs| [fs.service, "#{fs.host_from}:#{fs.port_from}", " => ", "#{fs.remote_host}:#{fs.port_to.to_s}"] end, :header => ["Service", "Local", " ", "OpenShift"] ) end end # for failed port forwarding attempts failed_port_forwards = forwarding_specs.select { |fs| !fs.bound? } if failed_port_forwards.length > 0 ssh_cmd_arg = failed_port_forwards.map { |fs| fs.to_cmd_arg }.join(" ") ssh_cmd = "ssh -N #{ssh_cmd_arg} #{ssh_uri.user}@#{ssh_uri.host}" warn "Error forwarding some port(s). You can try to forward manually by running:\n#{ssh_cmd}" else say "Press CTRL-C to terminate port forwarding" end unless forwarding_specs.any?(&:bound?) warn "No ports have been bound" return end ssh.loop { true } end rescue Interrupt say " Ending port forward" return 0 end end rescue Timeout::Error, Errno::EADDRNOTAVAIL, Errno::EADDRINUSE, Errno::EHOSTUNREACH, Errno::ECONNREFUSED, Net::SSH::AuthenticationFailed => e ssh_cmd = ["ssh","-N"] unbound_fs = forwarding_specs.select { |fs| !fs.bound? } ssh_cmd += unbound_fs.map { |fs| fs.to_cmd_arg } ssh_cmd += ["#{ssh_uri.user}@#{ssh_uri.host}"] raise RHC::PortForwardFailedException.new("#{e. + "\n" if .debug}Error trying to forward ports. You can try to forward manually by running:\n" + ssh_cmd.join(" ")) end 0 rescue RHC::Rest::ConnectionException => e error "Connection to #{openshift_server} failed: #{e.}" 1 end |