console-vmc-plugin 0.0.1

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/Rakefile ADDED
@@ -0,0 +1,47 @@
1
+ require "rake"
2
+
3
+ $LOAD_PATH.unshift File.expand_path("../lib", __FILE__)
4
+ require "console-vmc-plugin/version"
5
+
6
+ task :default => :spec
7
+
8
+ desc "Run specs"
9
+ task :spec => ["bundler:install", "test:spec"]
10
+
11
+ desc "Run integration tests"
12
+ task :test => ["bundler:install", "test:integration"]
13
+
14
+ task :build do
15
+ sh "gem build console-vmc-plugin.gemspec"
16
+ end
17
+
18
+ task :install => :build do
19
+ sh "gem install --local console-vmc-plugin-#{VMCConsole::VERSION}.gem"
20
+ end
21
+
22
+ task :uninstall do
23
+ sh "gem uninstall console-vmc-plugin"
24
+ end
25
+
26
+ task :reinstall => [:uninstall, :install]
27
+
28
+ task :release => :build do
29
+ sh "gem push console-vmc-plugin-#{VMCConsole::VERSION}.gem"
30
+ end
31
+
32
+ namespace "bundler" do
33
+ desc "Install gems"
34
+ task "install" do
35
+ sh("bundle install")
36
+ end
37
+ end
38
+
39
+ namespace "test" do
40
+ task "spec" do |t|
41
+ # nothing
42
+ end
43
+
44
+ task "integration" do |t|
45
+ sh("cd spec && bundle exec rake spec")
46
+ end
47
+ end
@@ -0,0 +1,171 @@
1
+ require "net/telnet"
2
+ require "readline"
3
+
4
+ require "tunnel-vmc-plugin/tunnel"
5
+
6
+
7
+ class CFConsole < CFTunnel
8
+ def initialize(client, app, port = 10000)
9
+ @client = client
10
+ @app = app
11
+ @port = port
12
+ end
13
+
14
+ def get_connection_info(auth)
15
+ unless console = @app.instances[0].console
16
+ raise "App does not have console access; try restarting it."
17
+ end
18
+
19
+ { "hostname" => console[:ip],
20
+ "port" => console[:port]
21
+ }
22
+ end
23
+
24
+ def get_credentials
25
+ YAML.load(@app.file("app", "cf-rails-console", ".consoleaccess"))
26
+ end
27
+
28
+ def start_console
29
+ prompt = login
30
+
31
+ init_readline
32
+
33
+ run_console prompt
34
+ end
35
+
36
+ def login(auth = get_credentials)
37
+ if !auth["username"] || !auth["password"]
38
+ raise "Unable to verify console credentials."
39
+ end
40
+
41
+ @telnet = telnet_client
42
+
43
+ prompt = nil
44
+ err_msg = "Login attempt timed out."
45
+
46
+ 5.times do
47
+ begin
48
+ results = @telnet.login(
49
+ "Name" => auth["username"],
50
+ "Password" => auth["password"])
51
+
52
+ lines = results.sub("Login: Password: ", "").split("\n")
53
+
54
+ last_line = lines.pop
55
+
56
+ if last_line =~ /[$%#>] \z/n
57
+ prompt = last_line
58
+ elsif last_line =~ /Login failed/
59
+ err_msg = last_line
60
+ end
61
+
62
+ break
63
+
64
+ rescue TimeoutError
65
+ sleep 1
66
+
67
+ rescue EOFError
68
+ # This may happen if we login right after app starts
69
+ close_console
70
+ sleep 5
71
+ @telnet = telnet_client
72
+ end
73
+ end
74
+
75
+ unless prompt
76
+ close_console
77
+ raise err_msg
78
+ end
79
+
80
+ prompt
81
+ end
82
+
83
+ private
84
+
85
+ def init_readline
86
+ if Readline.respond_to?("basic_word_break_characters=")
87
+ Readline.basic_word_break_characters= " \t\n`><=;|&{("
88
+ end
89
+
90
+ Readline.completion_append_character = nil
91
+
92
+ # Assumes that sending a String ending with tab will return a non-empty
93
+ # String of comma-separated completion options, terminated by a new line
94
+ # For example, "app.\t" might result in "to_s,nil?,etc\n"
95
+ Readline.completion_proc = proc do |s|
96
+ console_tab_completion_data(s)
97
+ end
98
+ end
99
+
100
+ def run_console(prompt)
101
+ prev = trap("INT") { |x| exit_console; prev.call(x); exit }
102
+ prev = trap("TERM") { |x| exit_console; prev.call(x); exit }
103
+
104
+ loop do
105
+ cmd = readline_with_history(prompt)
106
+
107
+ if cmd == nil
108
+ exit_console
109
+ break
110
+ end
111
+
112
+ prompt = send_console_command_display_results(cmd, prompt)
113
+ end
114
+ end
115
+
116
+ def readline_with_history(prompt)
117
+ line = Readline::readline(prompt)
118
+
119
+ return if line == nil || line == 'quit' || line == 'exit'
120
+
121
+ if line !~ /^\s*$/ && Readline::HISTORY.to_a[-1] != line
122
+ Readline::HISTORY.push(line)
123
+ end
124
+
125
+ line
126
+ end
127
+
128
+ def send_console_command_display_results(cmd, prompt)
129
+ begin
130
+ lines = send_console_command cmd
131
+
132
+ # Assumes the last line is a prompt
133
+ prompt = lines.pop
134
+
135
+ lines.each do |line|
136
+ puts line if line != cmd
137
+ end
138
+
139
+ rescue TimeoutError
140
+ puts "Timed out sending command to server."
141
+
142
+ rescue EOFError
143
+ raise "The console connection has been terminated. Perhaps the app was stopped or deleted?"
144
+ end
145
+
146
+ prompt
147
+ end
148
+
149
+ def send_console_command(cmd)
150
+ results = @telnet.cmd(cmd)
151
+ results.split("\n")
152
+ end
153
+
154
+ def exit_console
155
+ # TimeoutError expected, as exit doesn't return anything
156
+ @telnet.cmd("String" => "exit", "Timeout" => 1) rescue TimeoutError
157
+ close_console
158
+ end
159
+
160
+ def close_console
161
+ @telnet.close
162
+ end
163
+
164
+ def telnet_client
165
+ Net::Telnet.new(
166
+ "Port" => @port,
167
+ "Prompt" => /[$%#>] \z|Login failed/n,
168
+ "Timeout" => 30,
169
+ "FailEOF" => true)
170
+ end
171
+ end
@@ -0,0 +1,33 @@
1
+ require "vmc/plugin"
2
+ require "console-vmc-plugin/console"
3
+
4
+ module VMCConsole
5
+ class Console < VMC::CLI
6
+ desc "Open a console connected to your app"
7
+ group :apps, :manage
8
+ input :app, :argument => :required, :from_given => by_name("app"),
9
+ :desc => "App to connect to"
10
+ input :port, :default => 10000
11
+ def console
12
+ app = input[:app]
13
+
14
+ console = CFConsole.new(client, app)
15
+ port = console.pick_port!(input[:port])
16
+
17
+ with_progress("Opening console on port #{c(port, :name)}") do
18
+ console.open!
19
+ console.wait_for_start
20
+ end
21
+
22
+ console.start_console
23
+ end
24
+
25
+ filter(:start, :start_app) do |app|
26
+ if !v2? && app.framework.name == "rails3"
27
+ app.console = true
28
+ end
29
+
30
+ app
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,3 @@
1
+ module VMCConsole
2
+ VERSION = "0.0.1"
3
+ end
metadata ADDED
@@ -0,0 +1,84 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: console-vmc-plugin
3
+ version: !ruby/object:Gem::Version
4
+ hash: 29
5
+ prerelease:
6
+ segments:
7
+ - 0
8
+ - 0
9
+ - 1
10
+ version: 0.0.1
11
+ platform: ruby
12
+ authors:
13
+ - Alex Suraci
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2012-09-17 00:00:00 Z
19
+ dependencies:
20
+ - !ruby/object:Gem::Dependency
21
+ name: tunnel-vmc-plugin
22
+ prerelease: false
23
+ requirement: &id001 !ruby/object:Gem::Requirement
24
+ none: false
25
+ requirements:
26
+ - - ~>
27
+ - !ruby/object:Gem::Version
28
+ hash: 31
29
+ segments:
30
+ - 0
31
+ - 1
32
+ - 2
33
+ version: 0.1.2
34
+ type: :runtime
35
+ version_requirements: *id001
36
+ description:
37
+ email:
38
+ - asuraci@vmware.com
39
+ executables: []
40
+
41
+ extensions: []
42
+
43
+ extra_rdoc_files: []
44
+
45
+ files:
46
+ - Rakefile
47
+ - lib/console-vmc-plugin/console.rb
48
+ - lib/console-vmc-plugin/plugin.rb
49
+ - lib/console-vmc-plugin/version.rb
50
+ homepage: http://cloudfoundry.com/
51
+ licenses: []
52
+
53
+ post_install_message:
54
+ rdoc_options: []
55
+
56
+ require_paths:
57
+ - lib
58
+ required_ruby_version: !ruby/object:Gem::Requirement
59
+ none: false
60
+ requirements:
61
+ - - ">="
62
+ - !ruby/object:Gem::Version
63
+ hash: 3
64
+ segments:
65
+ - 0
66
+ version: "0"
67
+ required_rubygems_version: !ruby/object:Gem::Requirement
68
+ none: false
69
+ requirements:
70
+ - - ">="
71
+ - !ruby/object:Gem::Version
72
+ hash: 3
73
+ segments:
74
+ - 0
75
+ version: "0"
76
+ requirements: []
77
+
78
+ rubyforge_project: console-vmc-plugin
79
+ rubygems_version: 1.8.24
80
+ signing_key:
81
+ specification_version: 3
82
+ summary: Port of rails-console to vmc-ng.
83
+ test_files: []
84
+