lib/cli/commands/apps.rb in vmc-0.3.16.beta.2 vs lib/cli/commands/apps.rb in vmc-0.3.16.beta.3
- old
+ new
@@ -2,16 +2,20 @@
require 'fileutils'
require 'pathname'
require 'tempfile'
require 'tmpdir'
require 'set'
+require "uuidtools"
+require 'socket'
module VMC::Cli::Command
class Apps < Base
include VMC::Cli::ServicesHelper
include VMC::Cli::ManifestHelper
+ include VMC::Cli::TunnelHelper
+ include VMC::Cli::ConsoleHelper
def list
apps = client.apps
apps.sort! {|a, b| a[:name] <=> b[:name] }
return display JSON.pretty_generate(apps || []) if @options[:json]
@@ -41,10 +45,56 @@
def info(what, default=nil)
@options[what] || (@app_info && @app_info[what.to_s]) || default
end
+ def console(appname, interactive=true)
+ unless defined? Caldecott
+ display "To use `vmc rails-console', 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
+
+ #Make sure there is a console we can connect to first
+ conn_info = console_connection_info appname
+
+ port = pick_tunnel_port(@options[:port] || 20000)
+
+ 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)
+ 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)
+ start_caldecott
+ end
+
+ start_tunnel(port, conn_info, auth)
+ wait_for_tunnel_start(port)
+ start_local_console(port, appname) if interactive
+ port
+ end
+
def start(appname=nil, push=false)
if appname
do_start(appname, push)
else
each_app do |name|
@@ -71,18 +121,10 @@
def restart(appname=nil)
stop(appname)
start(appname)
end
- def rename(appname, newname)
- app = client.app_info(appname)
- app[:name] = newname
- display 'Renaming Appliction: '
- client.update_app(newname, app)
- display 'OK'.green
- end
-
def mem(appname, memsize=nil)
app = client.app_info(appname)
mem = current_mem = mem_quota_to_choice(app[:resources][:memory])
memsize = normalize_mem(memsize) if memsize
@@ -134,11 +176,11 @@
end
def delete(appname=nil)
force = @options[:force]
if @options[:all]
- if no_prompt || force || ask("Delete ALL applications and services?", :default => false)
+ if no_prompt || force || ask("Delete ALL applications?", :default => false)
apps = client.apps
apps.each { |app| delete_app(app[:name], force) }
end
else
err 'No valid appname given' unless appname
@@ -149,11 +191,11 @@
def files(appname, path='/')
return all_files(appname, path) if @options[:all] && !@options[:instance]
instance = @options[:instance] || '0'
content = client.app_files(appname, path, instance)
display content
- rescue VMC::Client::NotFound => e
+ rescue VMC::Client::TargetError
err 'No such file or directory'
end
def logs(appname)
# Check if we have an app before progressing further
@@ -649,11 +691,11 @@
def grab_logs(appname, instance)
log_file_paths.each do |path|
begin
content = client.app_files(appname, path, instance)
display_logfile(path, content, instance)
- rescue VMC::Client::NotFound
+ rescue VMC::Client::TargetError
end
end
end
def grab_crash_logs(appname, instance, was_staged=false)
@@ -663,17 +705,18 @@
instance ||= '0'
map = VMC::Cli::Config.instances
instance = map[instance] if map[instance]
%w{
- /logs/err.log /logs/staging.log /app/logs/stderr.log
- /app/logs/stdout.log /app/logs/startup.log /app/logs/migration.log
+ /logs/err.log /logs/staging.log /logs/migration.log
+ /app/logs/stderr.log /app/logs/stdout.log /app/logs/startup.log
+ /app/logs/migration.log
}.each do |path|
begin
content = client.app_files(appname, path, instance)
display_logfile(path, content, instance)
- rescue VMC::Client::NotFound
+ rescue VMC::Client::TargetError
end
end
end
def grab_startup_tail(appname, since = 0)
@@ -687,10 +730,12 @@
tail = response_lines[since, lines] || []
new_lines = tail.size
display tail.join("\n") if new_lines > 0
end
since + new_lines
+ rescue VMC::Client::TargetError
+ 0
end
def provisioned_services_apps_hash
apps = client.apps
services_apps_hash = {}
@@ -742,14 +787,15 @@
end
end
def do_start(appname, push=false)
app = client.app_info(appname)
-
return display "Application '#{appname}' could not be found".red if app.nil?
return display "Application '#{appname}' already started".yellow if app[:state] == 'STARTED'
+
+
if @options[:debug]
runtimes = client.runtimes_info
return display "Cannot get runtime information." unless runtimes
runtime = runtimes[app[:staging][:stack].to_sym]
@@ -782,10 +828,11 @@
end
end
app[:state] = 'STARTED'
app[:debug] = @options[:debug]
+ app[:console] = VMC::Cli::Framework.lookup_by_framework(app[:staging][:model]).console
client.update_app(appname, app)
Thread.kill(t)
clear(LINE_LENGTH)
display "#{banner}#{'OK'.green}"
@@ -798,28 +845,27 @@
start_time = Time.now.to_i
loop do
display '.', false unless count > TICKER_TICKS
sleep SLEEP_TIME
- begin
- break if app_started_properly(appname, count > HEALTH_TICKS)
- if !crashes(appname, false, start_time).empty?
- # Check for the existance of crashes
- display "\nError: Application [#{appname}] failed to start, logs information below.\n".red
- grab_crash_logs(appname, '0', true)
- if push and !no_prompt
- display "\n"
- delete_app(appname, false) if ask "Delete the application?", :default => true
- end
- failed = true
- break
- elsif count > TAIL_TICKS
- log_lines_displayed = grab_startup_tail(appname, log_lines_displayed)
+
+ break if app_started_properly(appname, count > HEALTH_TICKS)
+
+ if !crashes(appname, false, start_time).empty?
+ # Check for the existance of crashes
+ display "\nError: Application [#{appname}] failed to start, logs information below.\n".red
+ grab_crash_logs(appname, '0', true)
+ if push and !no_prompt
+ display "\n"
+ delete_app(appname, false) if ask "Delete the application?", :default => true
end
- rescue => e
- err(e.message, '')
+ failed = true
+ break
+ elsif count > TAIL_TICKS
+ log_lines_displayed = grab_startup_tail(appname, log_lines_displayed)
end
+
count += 1
if count > GIVEUP_TICKS # 2 minutes
display "\nApplication is taking too long to start, check your logs".yellow
break
end
@@ -887,11 +933,11 @@
if !app_checked and app_exists?(appname)
err "Application '#{appname}' already exists, use update or delete."
end
- default_url = "#{appname}.#{VMC::Cli::Config.suggest_url}"
+ default_url = "#{appname}.#{target_base}"
unless no_prompt || url
url = ask(
"Application Deployed URL",
:default => default_url
@@ -1016,10 +1062,10 @@
path,
content,
entry[:index],
"====> [#{entry[:index]}: #{path}] <====\n".bold
)
- rescue VMC::Client::NotFound
+ rescue VMC::Client::TargetError
end
end
end
end