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

Sign up to get free protection for your applications and to get access to all the features.
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