lib/cli/commands/services.rb in af-0.3.13.beta.5 vs lib/cli/commands/services.rb in af-0.3.16.1
- old
+ new
@@ -1,9 +1,12 @@
+require "uuidtools"
+
module VMC::Cli::Command
class Services < Base
include VMC::Cli::ServicesHelper
+ include VMC::Cli::TunnelHelper
def services
ss = client.services_info
ps = client.services
ps.sort! {|a, b| a[:name] <=> b[:name] }
@@ -79,7 +82,99 @@
err 'No services to clone' unless services && !services.empty?
services.each { |service| bind_service_banner(service, dest_app, false) }
check_app_for_restart(dest_app)
end
+ def tunnel(service=nil, client_name=nil)
+ unless defined? Caldecott
+ display "To use `vmc tunnel', you must first install Caldecott:"
+ display ""
+ display "\tgem install caldecott"
+ display ""
+ display "Note that you'll need a C compiler. If you're on OS X, Xcode"
+ display "will provide one. If you're on Windows, try DevKit."
+ display ""
+ display "This manual step will be removed in the future."
+ display ""
+ err "Caldecott is not installed."
+ end
+
+ ps = client.services
+ err "No services available to tunnel to" if ps.empty?
+
+ unless service
+ choices = ps.collect { |s| s[:name] }.sort
+ service = ask(
+ "Which service to tunnel to?",
+ :choices => choices,
+ :indexed => true
+ )
+ end
+
+ info = ps.select { |s| s[:name] == service }.first
+
+ err "Unknown service '#{service}'" unless info
+
+ port = pick_tunnel_port(@options[:port] || 10000)
+
+ raise VMC::Client::AuthError unless client.logged_in?
+
+ if not tunnel_pushed?
+ display "Deploying tunnel application '#{tunnel_appname}'."
+ auth = UUIDTools::UUID.random_create.to_s
+ push_caldecott(auth)
+ bind_service_banner(service, tunnel_appname, false)
+ start_caldecott
+ else
+ auth = tunnel_auth
+ end
+
+ if not tunnel_healthy?(auth)
+ display "Redeploying tunnel application '#{tunnel_appname}'."
+
+ # We don't expect caldecott not to be running, so take the
+ # most aggressive restart method.. delete/re-push
+ client.delete_app(tunnel_appname)
+ invalidate_tunnel_app_info
+
+ push_caldecott(auth)
+ bind_service_banner(service, tunnel_appname, false)
+ start_caldecott
+ end
+
+ if not tunnel_bound?(service)
+ bind_service_banner(service, tunnel_appname)
+ end
+
+ conn_info = tunnel_connection_info info[:vendor], service, auth
+ display_tunnel_connection_info(conn_info)
+ display "Starting tunnel to #{service.bold} on port #{port.to_s.bold}."
+ start_tunnel(port, conn_info, auth)
+
+ clients = get_clients_for(info[:vendor])
+
+ if clients.empty?
+ client_name ||= "none"
+ else
+ client_name ||= ask(
+ "Which client would you like to start?",
+ :choices => ["none"] + clients.keys,
+ :indexed => true
+ )
+ end
+
+ if client_name == "none"
+ wait_for_tunnel_end
+ else
+ wait_for_tunnel_start(port)
+ unless start_local_prog(clients, client_name, conn_info, port)
+ err "'#{client_name}' executation failed; is it in your $PATH?"
+ end
+ end
+ end
+
+ def get_clients_for(type)
+ conf = VMC::Cli::Config.clients
+ conf[type] || {}
+ end
end
end