vmc 0.3.16.beta.2 → 0.3.16.beta.3

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/README.md CHANGED
@@ -31,7 +31,6 @@ MIT license, please see the LICENSE file. All rights reserved._
31
31
  stop <appname> Stop the application
32
32
  restart <appname> Restart the application
33
33
  delete <appname> Delete the application
34
- rename <appname> <newname> Rename the application
35
34
 
36
35
  Application Updates
37
36
  update <appname> [--path] Update the application bits
data/lib/cli.rb CHANGED
@@ -13,6 +13,7 @@ module VMC
13
13
  autoload :ServicesHelper, "#{ROOT}/cli/services_helper"
14
14
  autoload :TunnelHelper, "#{ROOT}/cli/tunnel_helper"
15
15
  autoload :ManifestHelper, "#{ROOT}/cli/manifest_helper"
16
+ autoload :ConsoleHelper, "#{ROOT}/cli/console_helper"
16
17
 
17
18
  module Command
18
19
  autoload :Base, "#{ROOT}/cli/commands/base"
@@ -4,12 +4,16 @@ require 'pathname'
4
4
  require 'tempfile'
5
5
  require 'tmpdir'
6
6
  require 'set'
7
+ require "uuidtools"
8
+ require 'socket'
7
9
 
8
10
  module VMC::Cli::Command
9
11
 
10
12
  class Apps < Base
11
13
  include VMC::Cli::ServicesHelper
12
14
  include VMC::Cli::ManifestHelper
15
+ include VMC::Cli::TunnelHelper
16
+ include VMC::Cli::ConsoleHelper
13
17
 
14
18
  def list
15
19
  apps = client.apps
@@ -43,6 +47,52 @@ module VMC::Cli::Command
43
47
  @options[what] || (@app_info && @app_info[what.to_s]) || default
44
48
  end
45
49
 
50
+ def console(appname, interactive=true)
51
+ unless defined? Caldecott
52
+ display "To use `vmc rails-console', you must first install Caldecott:"
53
+ display ""
54
+ display "\tgem install caldecott"
55
+ display ""
56
+ display "Note that you'll need a C compiler. If you're on OS X, Xcode"
57
+ display "will provide one. If you're on Windows, try DevKit."
58
+ display ""
59
+ display "This manual step will be removed in the future."
60
+ display ""
61
+ err "Caldecott is not installed."
62
+ end
63
+
64
+ #Make sure there is a console we can connect to first
65
+ conn_info = console_connection_info appname
66
+
67
+ port = pick_tunnel_port(@options[:port] || 20000)
68
+
69
+ raise VMC::Client::AuthError unless client.logged_in?
70
+
71
+ if not tunnel_pushed?
72
+ display "Deploying tunnel application '#{tunnel_appname}'."
73
+ auth = UUIDTools::UUID.random_create.to_s
74
+ push_caldecott(auth)
75
+ start_caldecott
76
+ else
77
+ auth = tunnel_auth
78
+ end
79
+
80
+ if not tunnel_healthy?(auth)
81
+ display "Redeploying tunnel application '#{tunnel_appname}'."
82
+ # We don't expect caldecott not to be running, so take the
83
+ # most aggressive restart method.. delete/re-push
84
+ client.delete_app(tunnel_appname)
85
+ invalidate_tunnel_app_info
86
+ push_caldecott(auth)
87
+ start_caldecott
88
+ end
89
+
90
+ start_tunnel(port, conn_info, auth)
91
+ wait_for_tunnel_start(port)
92
+ start_local_console(port, appname) if interactive
93
+ port
94
+ end
95
+
46
96
  def start(appname=nil, push=false)
47
97
  if appname
48
98
  do_start(appname, push)
@@ -73,14 +123,6 @@ module VMC::Cli::Command
73
123
  start(appname)
74
124
  end
75
125
 
76
- def rename(appname, newname)
77
- app = client.app_info(appname)
78
- app[:name] = newname
79
- display 'Renaming Appliction: '
80
- client.update_app(newname, app)
81
- display 'OK'.green
82
- end
83
-
84
126
  def mem(appname, memsize=nil)
85
127
  app = client.app_info(appname)
86
128
  mem = current_mem = mem_quota_to_choice(app[:resources][:memory])
@@ -136,7 +178,7 @@ module VMC::Cli::Command
136
178
  def delete(appname=nil)
137
179
  force = @options[:force]
138
180
  if @options[:all]
139
- if no_prompt || force || ask("Delete ALL applications and services?", :default => false)
181
+ if no_prompt || force || ask("Delete ALL applications?", :default => false)
140
182
  apps = client.apps
141
183
  apps.each { |app| delete_app(app[:name], force) }
142
184
  end
@@ -151,7 +193,7 @@ module VMC::Cli::Command
151
193
  instance = @options[:instance] || '0'
152
194
  content = client.app_files(appname, path, instance)
153
195
  display content
154
- rescue VMC::Client::NotFound => e
196
+ rescue VMC::Client::TargetError
155
197
  err 'No such file or directory'
156
198
  end
157
199
 
@@ -651,7 +693,7 @@ module VMC::Cli::Command
651
693
  begin
652
694
  content = client.app_files(appname, path, instance)
653
695
  display_logfile(path, content, instance)
654
- rescue VMC::Client::NotFound
696
+ rescue VMC::Client::TargetError
655
697
  end
656
698
  end
657
699
  end
@@ -665,13 +707,14 @@ module VMC::Cli::Command
665
707
  instance = map[instance] if map[instance]
666
708
 
667
709
  %w{
668
- /logs/err.log /logs/staging.log /app/logs/stderr.log
669
- /app/logs/stdout.log /app/logs/startup.log /app/logs/migration.log
710
+ /logs/err.log /logs/staging.log /logs/migration.log
711
+ /app/logs/stderr.log /app/logs/stdout.log /app/logs/startup.log
712
+ /app/logs/migration.log
670
713
  }.each do |path|
671
714
  begin
672
715
  content = client.app_files(appname, path, instance)
673
716
  display_logfile(path, content, instance)
674
- rescue VMC::Client::NotFound
717
+ rescue VMC::Client::TargetError
675
718
  end
676
719
  end
677
720
  end
@@ -689,6 +732,8 @@ module VMC::Cli::Command
689
732
  display tail.join("\n") if new_lines > 0
690
733
  end
691
734
  since + new_lines
735
+ rescue VMC::Client::TargetError
736
+ 0
692
737
  end
693
738
 
694
739
  def provisioned_services_apps_hash
@@ -744,10 +789,11 @@ module VMC::Cli::Command
744
789
 
745
790
  def do_start(appname, push=false)
746
791
  app = client.app_info(appname)
747
-
748
792
  return display "Application '#{appname}' could not be found".red if app.nil?
749
793
  return display "Application '#{appname}' already started".yellow if app[:state] == 'STARTED'
750
794
 
795
+
796
+
751
797
  if @options[:debug]
752
798
  runtimes = client.runtimes_info
753
799
  return display "Cannot get runtime information." unless runtimes
@@ -784,6 +830,7 @@ module VMC::Cli::Command
784
830
 
785
831
  app[:state] = 'STARTED'
786
832
  app[:debug] = @options[:debug]
833
+ app[:console] = VMC::Cli::Framework.lookup_by_framework(app[:staging][:model]).console
787
834
  client.update_app(appname, app)
788
835
 
789
836
  Thread.kill(t)
@@ -800,24 +847,23 @@ module VMC::Cli::Command
800
847
  loop do
801
848
  display '.', false unless count > TICKER_TICKS
802
849
  sleep SLEEP_TIME
803
- begin
804
- break if app_started_properly(appname, count > HEALTH_TICKS)
805
- if !crashes(appname, false, start_time).empty?
806
- # Check for the existance of crashes
807
- display "\nError: Application [#{appname}] failed to start, logs information below.\n".red
808
- grab_crash_logs(appname, '0', true)
809
- if push and !no_prompt
810
- display "\n"
811
- delete_app(appname, false) if ask "Delete the application?", :default => true
812
- end
813
- failed = true
814
- break
815
- elsif count > TAIL_TICKS
816
- log_lines_displayed = grab_startup_tail(appname, log_lines_displayed)
850
+
851
+ break if app_started_properly(appname, count > HEALTH_TICKS)
852
+
853
+ if !crashes(appname, false, start_time).empty?
854
+ # Check for the existance of crashes
855
+ display "\nError: Application [#{appname}] failed to start, logs information below.\n".red
856
+ grab_crash_logs(appname, '0', true)
857
+ if push and !no_prompt
858
+ display "\n"
859
+ delete_app(appname, false) if ask "Delete the application?", :default => true
817
860
  end
818
- rescue => e
819
- err(e.message, '')
861
+ failed = true
862
+ break
863
+ elsif count > TAIL_TICKS
864
+ log_lines_displayed = grab_startup_tail(appname, log_lines_displayed)
820
865
  end
866
+
821
867
  count += 1
822
868
  if count > GIVEUP_TICKS # 2 minutes
823
869
  display "\nApplication is taking too long to start, check your logs".yellow
@@ -889,7 +935,7 @@ module VMC::Cli::Command
889
935
  err "Application '#{appname}' already exists, use update or delete."
890
936
  end
891
937
 
892
- default_url = "#{appname}.#{VMC::Cli::Config.suggest_url}"
938
+ default_url = "#{appname}.#{target_base}"
893
939
 
894
940
  unless no_prompt || url
895
941
  url = ask(
@@ -1018,7 +1064,7 @@ module VMC::Cli::Command
1018
1064
  entry[:index],
1019
1065
  "====> [#{entry[:index]}: #{path}] <====\n".bold
1020
1066
  )
1021
- rescue VMC::Client::NotFound
1067
+ rescue VMC::Client::TargetError
1022
1068
  end
1023
1069
  end
1024
1070
  end
@@ -8,7 +8,6 @@ module VMC::Cli
8
8
 
9
9
  class Base
10
10
  include Interactive
11
- disable_rewind
12
11
 
13
12
  attr_reader :no_prompt, :prompt_ok
14
13
 
@@ -173,15 +172,13 @@ module VMC::Cli
173
172
  end
174
173
 
175
174
  def target_url(ctx = [])
176
- find_symbol("target", ctx) || VMC::Cli::Config.target_url
175
+ find_symbol("target", ctx) ||
176
+ (@client && @client.target) ||
177
+ VMC::Cli::Config.target_url
177
178
  end
178
179
 
179
180
  def target_base(ctx = [])
180
- if tgt = find_symbol("target", ctx)
181
- VMC::Cli::Config.base_of(tgt)
182
- else
183
- VMC::Cli::Config.suggest_url
184
- end
181
+ VMC::Cli::Config.base_of(find_symbol("target", ctx) || target_url)
185
182
  end
186
183
 
187
184
  # Inject a client to help in testing.
@@ -147,7 +147,8 @@ module VMC::Cli::Command
147
147
 
148
148
  conn_info = tunnel_connection_info info[:vendor], service, auth
149
149
  display_tunnel_connection_info(conn_info)
150
- start_tunnel(service, port, conn_info, auth)
150
+ display "Starting tunnel to #{service.bold} on port #{port.to_s.bold}."
151
+ start_tunnel(port, conn_info, auth)
151
152
 
152
153
  clients = get_clients_for(info[:vendor])
153
154
 
@@ -8,7 +8,6 @@ module VMC::Cli
8
8
  class Config
9
9
 
10
10
  DEFAULT_TARGET = 'api.vcap.me'
11
- DEFAULT_SUGGEST = 'vcap.me'
12
11
 
13
12
  TARGET_FILE = '~/.vmc_target'
14
13
  TOKEN_FILE = '~/.vmc_token'
@@ -42,12 +41,7 @@ module VMC::Cli
42
41
  end
43
42
 
44
43
  def suggest_url
45
- return @suggest_url if @suggest_url
46
- ha = target_url.split('.')
47
- ha.shift
48
- @suggest_url = ha.join('.')
49
- @suggest_url = DEFAULT_SUGGEST if @suggest_url.empty?
50
- @suggest_url
44
+ @suggest_url ||= base_of(target_url)
51
45
  end
52
46
 
53
47
  def store_target(target_host)
@@ -124,8 +118,9 @@ module VMC::Cli
124
118
  return @clients if @clients
125
119
 
126
120
  stock = YAML.load_file(STOCK_CLIENTS)
127
- if File.exists? CLIENTS_FILE
128
- user = YAML.load_file(CLIENTS_FILE)
121
+ clients = File.expand_path CLIENTS_FILE
122
+ if File.exists? clients
123
+ user = YAML.load_file(clients)
129
124
  @clients = deep_merge(stock, user)
130
125
  else
131
126
  @clients = stock
@@ -0,0 +1,157 @@
1
+ require 'net/telnet'
2
+ require 'readline'
3
+
4
+ module VMC::Cli
5
+ module ConsoleHelper
6
+
7
+ def console_connection_info(appname)
8
+ app = client.app_info(appname)
9
+ fw = VMC::Cli::Framework.lookup_by_framework(app[:staging][:model])
10
+ if !fw.console
11
+ err "'#{appname}' is a #{fw.name} application. " +
12
+ "Console access is not supported for #{fw.name} applications."
13
+ end
14
+ instances_info_envelope = client.app_instances(appname)
15
+ instances_info_envelope = {} if instances_info_envelope.is_a?(Array)
16
+
17
+ instances_info = instances_info_envelope[:instances] || []
18
+ err "No running instances for [#{appname}]" if instances_info.empty?
19
+
20
+ entry = instances_info[0]
21
+ if !entry[:console_port]
22
+ begin
23
+ client.app_files(appname, '/app/cf-rails-console')
24
+ err "Console port not provided for [#{appname}]. Try restarting the app."
25
+ rescue VMC::Client::TargetError, VMC::Client::NotFound
26
+ err "Console access not supported for [#{appname}]. " +
27
+ "Please redeploy your app to enable support."
28
+ end
29
+ end
30
+ conn_info = {'hostname' => entry[:console_ip], 'port' => entry[:console_port]}
31
+ end
32
+
33
+ def start_local_console(port, appname)
34
+ auth_info = console_credentials(appname)
35
+ display "Connecting to '#{appname}' console: ", false
36
+ prompt = console_login(auth_info, port)
37
+ display "OK".green
38
+ display "\n"
39
+ initialize_readline
40
+ run_console prompt
41
+ end
42
+
43
+ def console_login(auth_info, port)
44
+ if !auth_info["username"] || !auth_info["password"]
45
+ err "Unable to verify console credentials."
46
+ end
47
+ @telnet_client = telnet_client(port)
48
+ prompt = nil
49
+ err_msg = "Login attempt timed out."
50
+ 5.times do
51
+ begin
52
+ results = @telnet_client.login("Name"=>auth_info["username"],
53
+ "Password"=>auth_info["password"]) {|line|
54
+ if line =~ /[$%#>] \z/n
55
+ prompt = line
56
+ elsif line =~ /Login failed/
57
+ err_msg = line
58
+ end
59
+ }
60
+ break
61
+ rescue TimeoutError
62
+ sleep 1
63
+ rescue EOFError
64
+ #This may happen if we login right after app starts
65
+ close_console
66
+ sleep 5
67
+ @telnet_client = telnet_client(port)
68
+ end
69
+ display ".", false
70
+ end
71
+ unless prompt
72
+ close_console
73
+ err err_msg
74
+ end
75
+ prompt
76
+ end
77
+
78
+ def send_console_command(cmd)
79
+ results = @telnet_client.cmd(cmd)
80
+ results.split("\n")
81
+ end
82
+
83
+ def console_credentials(appname)
84
+ content = client.app_files(appname, '/app/cf-rails-console/.consoleaccess', '0')
85
+ YAML.load(content)
86
+ end
87
+
88
+ def close_console
89
+ @telnet_client.close
90
+ end
91
+
92
+ def console_tab_completion_data(cmd)
93
+ begin
94
+ results = @telnet_client.cmd("String"=> cmd + "\t", "Match"=>/\S*\n$/, "Timeout"=>10)
95
+ results.chomp.split(",")
96
+ rescue TimeoutError
97
+ [] #Just return empty results if timeout occurred on tab completion
98
+ end
99
+ end
100
+
101
+ private
102
+ def telnet_client(port)
103
+ Net::Telnet.new({"Port"=>port, "Prompt"=>/[$%#>] \z|Login failed/n, "Timeout"=>30, "FailEOF"=>true})
104
+ end
105
+
106
+ def readline_with_history(prompt)
107
+ line = Readline.readline(prompt, true)
108
+ return '' if line.nil?
109
+ #Don't keep blank or repeat commands in history
110
+ if line =~ /^\s*$/ or Readline::HISTORY.to_a[-2] == line
111
+ Readline::HISTORY.pop
112
+ end
113
+ line
114
+ end
115
+
116
+ def run_console(prompt)
117
+ while(cmd = readline_with_history(prompt))
118
+ if(cmd == "exit" || cmd == "quit")
119
+ #TimeoutError expected, as exit doesn't return anything
120
+ @telnet_client.cmd("String"=>cmd,"Timeout"=>1) rescue TimeoutError
121
+ close_console
122
+ break
123
+ end
124
+ if !cmd.empty?
125
+ prompt = send_console_command_display_results(cmd, prompt)
126
+ end
127
+ end
128
+ end
129
+
130
+ def send_console_command_display_results(cmd, prompt)
131
+ begin
132
+ lines = send_console_command cmd
133
+ #Assumes the last line is a prompt
134
+ prompt = lines.pop
135
+ lines.each {|line| display line if line != cmd}
136
+ rescue TimeoutError
137
+ display "Timed out sending command to server.".red
138
+ rescue EOFError
139
+ err "The console connection has been terminated. Perhaps the app was stopped or deleted?"
140
+ end
141
+ prompt
142
+ end
143
+
144
+ def initialize_readline
145
+ if Readline.respond_to?("basic_word_break_characters=")
146
+ Readline.basic_word_break_characters= " \t\n`><=;|&{("
147
+ end
148
+ Readline.completion_append_character = nil
149
+ #Assumes that sending a String ending with tab will return a non-empty
150
+ #String of comma-separated completion options, terminated by a new line
151
+ #For example, "app.\t" might result in "to_s,nil?,etc\n"
152
+ Readline.completion_proc = proc {|s|
153
+ console_tab_completion_data s
154
+ }
155
+ end
156
+ end
157
+ end
@@ -6,7 +6,7 @@ module VMC::Cli
6
6
  DEFAULT_MEM = '256M'
7
7
 
8
8
  FRAMEWORKS = {
9
- 'Rails' => ['rails3', { :mem => '256M', :description => 'Rails Application'}],
9
+ 'Rails' => ['rails3', { :mem => '256M', :description => 'Rails Application', :console=>true}],
10
10
  'Spring' => ['spring', { :mem => '512M', :description => 'Java SpringSource Spring Application'}],
11
11
  'Grails' => ['grails', { :mem => '512M', :description => 'Java SpringSource Grails Application'}],
12
12
  'Lift' => ['lift', { :mem => '512M', :description => 'Scala Lift Application'}],
@@ -29,6 +29,12 @@ module VMC::Cli
29
29
  return Framework.new(*FRAMEWORKS[name])
30
30
  end
31
31
 
32
+ def lookup_by_framework(name)
33
+ FRAMEWORKS.each do |key,fw|
34
+ return Framework.new(fw[0], fw[1]) if fw[0] == name
35
+ end
36
+ end
37
+
32
38
  def detect(path)
33
39
  Dir.chdir(path) do
34
40
 
@@ -106,7 +112,7 @@ module VMC::Cli
106
112
 
107
113
  end
108
114
 
109
- attr_reader :name, :description, :memory
115
+ attr_reader :name, :description, :memory, :console
110
116
  attr_accessor :exec
111
117
 
112
118
  alias :mem :memory
@@ -116,6 +122,7 @@ module VMC::Cli
116
122
  @memory = opts[:mem] || DEFAULT_MEM
117
123
  @description = opts[:description] || 'Unknown Application Type'
118
124
  @exec = opts[:exec]
125
+ @console = opts[:console] || false
119
126
  end
120
127
 
121
128
  def to_s
@@ -125,10 +125,20 @@ module VMC::Cli::ManifestHelper
125
125
  ), "instances"
126
126
 
127
127
  unless manifest "services"
128
+ user_services = client.services
129
+ user_services.sort! {|a, b| a[:name] <=> b[:name] }
130
+
131
+ unless user_services.empty?
132
+ if ask "Bind existing services to '#{name}'?", :default => false
133
+ bind_services(user_services)
134
+ end
135
+ end
136
+
128
137
  services = client.services_info
129
138
  unless services.empty?
130
- bind = ask "Would you like to bind any services to '#{name}'?", :default => false
131
- bind_services(services.values.collect(&:keys).flatten) if bind
139
+ if ask "Create services to bind to '#{name}'?", :default => false
140
+ create_services(services.values.collect(&:keys).flatten)
141
+ end
132
142
  end
133
143
  end
134
144
 
@@ -174,20 +184,34 @@ module VMC::Cli::ManifestHelper
174
184
  framework
175
185
  end
176
186
 
177
- def bind_services(services)
187
+ def bind_services(user_services, chosen = 0)
188
+ svcname = ask(
189
+ "Which one?",
190
+ :indexed => true,
191
+ :choices => user_services.collect { |p| p[:name] })
192
+
193
+ svc = user_services.find { |p| p[:name] == svcname }
194
+
195
+ set svc[:vendor], "services", svcname, "type"
196
+
197
+ if chosen + 1 < user_services.size && ask("Bind another?", :default => false)
198
+ bind_services(user_services, chosen + 1)
199
+ end
200
+ end
201
+
202
+ def create_services(services)
178
203
  svcs = services.collect(&:to_s).sort!
179
204
 
180
- display "The following system services are available"
181
205
  configure_service(
182
206
  ask(
183
- "Please select the one you wish to provision",
207
+ "What kind of service?",
184
208
  :indexed => true,
185
209
  :choices => svcs
186
- ).to_sym
210
+ )
187
211
  )
188
212
 
189
- if ask "Would you like to bind another service?", :default => false
190
- bind_services(services)
213
+ if ask "Create another?", :default => false
214
+ create_services(services)
191
215
  end
192
216
  end
193
217
 
@@ -238,10 +238,6 @@ class VMC::Cli::Runner
238
238
  usage('vmc restart <appname>')
239
239
  set_cmd(:apps, :restart, @args.size == 1 ? 1 : 0)
240
240
 
241
- when 'rename'
242
- usage('vmc rename <appname> <newname>')
243
- set_cmd(:apps, :rename, 2)
244
-
245
241
  when 'mem'
246
242
  usage('vmc mem <appname> [memsize]')
247
243
  if @args.size == 2
@@ -380,6 +376,10 @@ class VMC::Cli::Runner
380
376
  set_cmd(:services, :tunnel, 1) if @args.size == 1
381
377
  set_cmd(:services, :tunnel, 2) if @args.size == 2
382
378
 
379
+ when 'rails-console'
380
+ usage('vmc rails-console <appname>')
381
+ set_cmd(:apps, :console, 1)
382
+
383
383
  when 'help'
384
384
  display_help if @args.size == 0
385
385
  @help_only = true
@@ -478,6 +478,7 @@ class VMC::Cli::Runner
478
478
  @exit_status = false
479
479
  rescue VMC::Client::TargetError, VMC::Client::NotFound, VMC::Client::BadTarget => e
480
480
  puts e.message.red
481
+ puts e.backtrace
481
482
  @exit_status = false
482
483
  rescue VMC::Client::HTTPException => e
483
484
  puts e.message.red
@@ -39,7 +39,6 @@ module VMC::Cli
39
39
  name, val = e.split("=", 2)
40
40
  return val if name == "CALDECOTT_AUTH"
41
41
  end
42
-
43
42
  nil
44
43
  end
45
44
 
@@ -184,9 +183,7 @@ module VMC::Cli
184
183
  display ''
185
184
  end
186
185
 
187
- def start_tunnel(service, local_port, conn_info, auth)
188
- display "Starting tunnel to #{service.bold} on port #{local_port.to_s.bold}."
189
-
186
+ def start_tunnel(local_port, conn_info, auth)
190
187
  @local_tunnel_thread = Thread.new do
191
188
  Caldecott::Client.start({
192
189
  :local_port => local_port,
@@ -203,6 +200,8 @@ module VMC::Cli
203
200
  at_exit { @local_tunnel_thread.kill }
204
201
  end
205
202
 
203
+
204
+
206
205
  def pick_tunnel_port(port)
207
206
  original = port
208
207
 
@@ -230,8 +229,9 @@ module VMC::Cli
230
229
  def wait_for_tunnel_start(port)
231
230
  10.times do |n|
232
231
  begin
233
- TCPSocket.open('localhost', port)
232
+ client = TCPSocket.open('localhost', port)
234
233
  display '' if n > 0
234
+ client.close
235
235
  return true
236
236
  rescue => e
237
237
  display "Waiting for local tunnel to become available", false if n == 0
@@ -297,28 +297,36 @@ module VMC::Cli
297
297
  tunnel_appname,
298
298
  { :name => tunnel_appname,
299
299
  :staging => {:framework => "sinatra"},
300
- :uris => ["#{tunnel_uniquename}.#{VMC::Cli::Config.suggest_url}"],
300
+ :uris => ["#{tunnel_uniquename}.#{target_base}"],
301
301
  :instances => 1,
302
302
  :resources => {:memory => 64},
303
303
  :env => ["CALDECOTT_AUTH=#{token}"]
304
304
  }
305
305
  )
306
306
 
307
- Command::Apps.new(@options).send(:upload_app_bits, tunnel_appname, HELPER_APP)
307
+ apps_cmd.send(:upload_app_bits, tunnel_appname, HELPER_APP)
308
308
 
309
309
  invalidate_tunnel_app_info
310
310
  end
311
311
 
312
312
  def stop_caldecott
313
- Command::Apps.new(@options).stop(tunnel_appname)
313
+ apps_cmd.stop(tunnel_appname)
314
314
 
315
315
  invalidate_tunnel_app_info
316
316
  end
317
317
 
318
318
  def start_caldecott
319
- Command::Apps.new(@options).start(tunnel_appname)
319
+ apps_cmd.start(tunnel_appname)
320
320
 
321
321
  invalidate_tunnel_app_info
322
322
  end
323
+
324
+ private
325
+
326
+ def apps_cmd
327
+ a = Command::Apps.new(@options)
328
+ a.client client
329
+ a
330
+ end
323
331
  end
324
332
  end
@@ -47,7 +47,6 @@ Currently available vmc commands are:
47
47
  stop <appname> Stop the application
48
48
  restart <appname> [--debug [MODE]] Restart the application
49
49
  delete <appname> Delete the application
50
- rename <appname> <newname> Rename the application
51
50
 
52
51
  Application Updates
53
52
  update <appname> [--path,--debug [MODE]] Update the application bits
@@ -2,6 +2,6 @@ module VMC
2
2
  module Cli
3
3
  # This version number is used as the RubyGem release version.
4
4
  # The internal VMC version number is VMC::VERSION.
5
- VERSION = '0.3.16.beta.2'
5
+ VERSION = '0.3.16.beta.3'
6
6
  end
7
7
  end
@@ -39,7 +39,7 @@ class VMC::Client
39
39
  def initialize(target_url=VMC::DEFAULT_TARGET, auth_token=nil)
40
40
  target_url = "http://#{target_url}" unless /^https?/ =~ target_url
41
41
  target_url = target_url.gsub(/\/+$/, '')
42
- @target = target_url
42
+ @target = target_url
43
43
  @auth_token = auth_token
44
44
  end
45
45
 
@@ -149,7 +149,7 @@ class VMC::Client
149
149
 
150
150
  # List the directory or download the actual file indicated by
151
151
  # the path.
152
- def app_files(name, path, instance=0)
152
+ def app_files(name, path, instance='0')
153
153
  check_login_status
154
154
  path = path.gsub('//', '/')
155
155
  url = path(VMC::APPS_PATH, name, "instances", instance, "files", path)
@@ -318,7 +318,7 @@ class VMC::Client
318
318
 
319
319
  def self.path(*path)
320
320
  path.flatten.collect { |x|
321
- URI.encode x, Regexp.new("[^#{URI::PATTERN::UNRESERVED}]")
321
+ URI.encode x.to_s, Regexp.new("[^#{URI::PATTERN::UNRESERVED}]")
322
322
  }.join("/")
323
323
  end
324
324
 
metadata CHANGED
@@ -2,7 +2,7 @@
2
2
  name: vmc
3
3
  version: !ruby/object:Gem::Version
4
4
  prerelease: 7
5
- version: 0.3.16.beta.2
5
+ version: 0.3.16.beta.3
6
6
  platform: ruby
7
7
  authors:
8
8
  - VMware
@@ -10,7 +10,7 @@ autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
12
 
13
- date: 2012-01-17 00:00:00 -08:00
13
+ date: 2012-02-07 00:00:00 -08:00
14
14
  default_executable:
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
@@ -71,7 +71,7 @@ dependencies:
71
71
  requirements:
72
72
  - - ~>
73
73
  - !ruby/object:Gem::Version
74
- version: 0.3.0
74
+ version: 0.4.0
75
75
  type: :runtime
76
76
  version_requirements: *id005
77
77
  - !ruby/object:Gem::Dependency
@@ -151,6 +151,7 @@ files:
151
151
  - lib/cli/commands/services.rb
152
152
  - lib/cli/commands/user.rb
153
153
  - lib/cli/config.rb
154
+ - lib/cli/console_helper.rb
154
155
  - lib/cli/core_ext.rb
155
156
  - lib/cli/errors.rb
156
157
  - lib/cli/frameworks.rb