vmc 0.4.0.beta.8 → 0.4.0.beta.9
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/{vmc-ng/LICENSE → LICENSE} +0 -0
- data/{vmc-ng/Rakefile → Rakefile} +0 -0
- data/bin/vmc +10 -11
- data/{vmc-ng/lib → lib}/vmc/cli/app.rb +106 -58
- data/{vmc-ng/lib → lib}/vmc/cli/better_help.rb +0 -0
- data/{vmc-ng/lib → lib}/vmc/cli/command.rb +14 -0
- data/{vmc-ng/lib → lib}/vmc/cli/dots.rb +0 -0
- data/{vmc-ng/lib → lib}/vmc/cli/service.rb +0 -0
- data/{vmc-ng/lib → lib}/vmc/cli/user.rb +0 -0
- data/{vmc-ng/lib → lib}/vmc/cli.rb +88 -2
- data/{vmc-ng/lib → lib}/vmc/constants.rb +0 -0
- data/{vmc-ng/lib → lib}/vmc/detect.rb +0 -0
- data/{vmc-ng/lib → lib}/vmc/errors.rb +0 -0
- data/{vmc-ng/lib → lib}/vmc/plugin.rb +0 -0
- data/lib/vmc/version.rb +3 -0
- data/{vmc-ng/lib → lib}/vmc.rb +0 -0
- metadata +41 -273
- data/vmc/LICENSE +0 -24
- data/vmc/README.md +0 -102
- data/vmc/Rakefile +0 -101
- data/vmc/bin/vmc +0 -6
- data/vmc/caldecott_helper/Gemfile +0 -10
- data/vmc/caldecott_helper/Gemfile.lock +0 -48
- data/vmc/caldecott_helper/server.rb +0 -43
- data/vmc/config/clients.yml +0 -17
- data/vmc/config/micro/offline.conf +0 -2
- data/vmc/config/micro/paths.yml +0 -22
- data/vmc/config/micro/refresh_ip.rb +0 -20
- data/vmc/lib/cli/commands/admin.rb +0 -80
- data/vmc/lib/cli/commands/apps.rb +0 -1126
- data/vmc/lib/cli/commands/base.rb +0 -227
- data/vmc/lib/cli/commands/manifest.rb +0 -56
- data/vmc/lib/cli/commands/micro.rb +0 -115
- data/vmc/lib/cli/commands/misc.rb +0 -129
- data/vmc/lib/cli/commands/services.rb +0 -180
- data/vmc/lib/cli/commands/user.rb +0 -65
- data/vmc/lib/cli/config.rb +0 -173
- data/vmc/lib/cli/console_helper.rb +0 -160
- data/vmc/lib/cli/core_ext.rb +0 -122
- data/vmc/lib/cli/errors.rb +0 -19
- data/vmc/lib/cli/frameworks.rb +0 -265
- data/vmc/lib/cli/manifest_helper.rb +0 -302
- data/vmc/lib/cli/runner.rb +0 -531
- data/vmc/lib/cli/services_helper.rb +0 -84
- data/vmc/lib/cli/tunnel_helper.rb +0 -332
- data/vmc/lib/cli/usage.rb +0 -115
- data/vmc/lib/cli/version.rb +0 -7
- data/vmc/lib/cli/zip_util.rb +0 -77
- data/vmc/lib/cli.rb +0 -47
- data/vmc/lib/vmc/client.rb +0 -471
- data/vmc/lib/vmc/const.rb +0 -22
- data/vmc/lib/vmc/micro/switcher/base.rb +0 -97
- data/vmc/lib/vmc/micro/switcher/darwin.rb +0 -19
- data/vmc/lib/vmc/micro/switcher/dummy.rb +0 -15
- data/vmc/lib/vmc/micro/switcher/linux.rb +0 -16
- data/vmc/lib/vmc/micro/switcher/windows.rb +0 -31
- data/vmc/lib/vmc/micro/vmrun.rb +0 -158
- data/vmc/lib/vmc/micro.rb +0 -56
- data/vmc/lib/vmc.rb +0 -3
- data/vmc-ng/bin/vmc +0 -14
- data/vmc-ng/lib/vmc/version.rb +0 -3
@@ -1,65 +0,0 @@
|
|
1
|
-
module VMC::Cli::Command
|
2
|
-
|
3
|
-
class User < Base
|
4
|
-
|
5
|
-
def info
|
6
|
-
info = client_info
|
7
|
-
username = info[:user] || 'N/A'
|
8
|
-
return display JSON.pretty_generate([username]) if @options[:json]
|
9
|
-
display "\n[#{username}]"
|
10
|
-
end
|
11
|
-
|
12
|
-
def login(email=nil)
|
13
|
-
email = @options[:email] unless email
|
14
|
-
password = @options[:password]
|
15
|
-
tries ||= 0
|
16
|
-
|
17
|
-
unless no_prompt
|
18
|
-
display "Attempting login to [#{target_url}]" if target_url
|
19
|
-
email ||= ask("Email")
|
20
|
-
password ||= ask("Password", :echo => "*")
|
21
|
-
end
|
22
|
-
|
23
|
-
err "Need a valid email" unless email
|
24
|
-
err "Need a password" unless password
|
25
|
-
login_and_save_token(email, password)
|
26
|
-
say "Successfully logged into [#{target_url}]".green
|
27
|
-
rescue VMC::Client::TargetError
|
28
|
-
display "Problem with login, invalid account or password when attempting to login to '#{target_url}'".red
|
29
|
-
retry if (tries += 1) < 3 && prompt_ok && !@options[:password]
|
30
|
-
exit 1
|
31
|
-
rescue => e
|
32
|
-
display "Problem with login to '#{target_url}', #{e}, try again or register for an account.".red
|
33
|
-
exit 1
|
34
|
-
end
|
35
|
-
|
36
|
-
def logout
|
37
|
-
VMC::Cli::Config.remove_token_file
|
38
|
-
say "Successfully logged out of [#{target_url}]".green
|
39
|
-
end
|
40
|
-
|
41
|
-
def change_password(password=nil)
|
42
|
-
info = client_info
|
43
|
-
email = info[:user]
|
44
|
-
err "Need to be logged in to change password." unless email
|
45
|
-
say "Changing password for '#{email}'\n"
|
46
|
-
unless no_prompt
|
47
|
-
password = ask "New Password", :echo => "*"
|
48
|
-
password2 = ask "Verify Password", :echo => "*"
|
49
|
-
err "Passwords did not match, try again" if password != password2
|
50
|
-
end
|
51
|
-
err "Password required" unless password
|
52
|
-
client.change_password(password)
|
53
|
-
say "\nSuccessfully changed password".green
|
54
|
-
end
|
55
|
-
|
56
|
-
private
|
57
|
-
|
58
|
-
def login_and_save_token(email, password)
|
59
|
-
token = client.login(email, password)
|
60
|
-
VMC::Cli::Config.store_token(token, @options[:token_file])
|
61
|
-
end
|
62
|
-
|
63
|
-
end
|
64
|
-
|
65
|
-
end
|
data/vmc/lib/cli/config.rb
DELETED
@@ -1,173 +0,0 @@
|
|
1
|
-
require "yaml"
|
2
|
-
require 'fileutils'
|
3
|
-
|
4
|
-
require 'rubygems'
|
5
|
-
require 'json/pure'
|
6
|
-
|
7
|
-
module VMC::Cli
|
8
|
-
class Config
|
9
|
-
|
10
|
-
DEFAULT_TARGET = 'api.vcap.me'
|
11
|
-
|
12
|
-
TARGET_FILE = '~/.vmc_target'
|
13
|
-
TOKEN_FILE = '~/.vmc_token'
|
14
|
-
INSTANCES_FILE = '~/.vmc_instances'
|
15
|
-
ALIASES_FILE = '~/.vmc_aliases'
|
16
|
-
CLIENTS_FILE = '~/.vmc_clients'
|
17
|
-
MICRO_FILE = '~/.vmc_micro'
|
18
|
-
|
19
|
-
STOCK_CLIENTS = File.expand_path("../../../config/clients.yml", __FILE__)
|
20
|
-
|
21
|
-
class << self
|
22
|
-
attr_accessor :colorize
|
23
|
-
attr_accessor :output
|
24
|
-
attr_accessor :trace
|
25
|
-
attr_accessor :nozip
|
26
|
-
|
27
|
-
def target_url
|
28
|
-
return @target_url if @target_url
|
29
|
-
target_file = File.expand_path(TARGET_FILE)
|
30
|
-
if File.exists? target_file
|
31
|
-
@target_url = lock_and_read(target_file).strip
|
32
|
-
else
|
33
|
-
@target_url = DEFAULT_TARGET
|
34
|
-
end
|
35
|
-
@target_url = "http://#{@target_url}" unless /^https?/ =~ @target_url
|
36
|
-
@target_url = @target_url.gsub(/\/+$/, '')
|
37
|
-
@target_url
|
38
|
-
end
|
39
|
-
|
40
|
-
def base_of(url)
|
41
|
-
url.sub(/^[^\.]+\./, "")
|
42
|
-
end
|
43
|
-
|
44
|
-
def suggest_url
|
45
|
-
@suggest_url ||= base_of(target_url)
|
46
|
-
end
|
47
|
-
|
48
|
-
def store_target(target_host)
|
49
|
-
target_file = File.expand_path(TARGET_FILE)
|
50
|
-
lock_and_write(target_file, target_host)
|
51
|
-
end
|
52
|
-
|
53
|
-
def all_tokens(token_file_path=nil)
|
54
|
-
token_file = File.expand_path(token_file_path || TOKEN_FILE)
|
55
|
-
return nil unless File.exists? token_file
|
56
|
-
contents = lock_and_read(token_file).strip
|
57
|
-
JSON.parse(contents)
|
58
|
-
end
|
59
|
-
|
60
|
-
alias :targets :all_tokens
|
61
|
-
|
62
|
-
def auth_token(token_file_path=nil)
|
63
|
-
return @token if @token
|
64
|
-
tokens = all_tokens(token_file_path)
|
65
|
-
@token = tokens[target_url] if tokens
|
66
|
-
end
|
67
|
-
|
68
|
-
def remove_token_file
|
69
|
-
FileUtils.rm_f(File.expand_path(TOKEN_FILE))
|
70
|
-
end
|
71
|
-
|
72
|
-
def store_token(token, token_file_path=nil)
|
73
|
-
tokens = all_tokens(token_file_path) || {}
|
74
|
-
tokens[target_url] = token
|
75
|
-
token_file = File.expand_path(token_file_path || TOKEN_FILE)
|
76
|
-
lock_and_write(token_file, tokens.to_json)
|
77
|
-
end
|
78
|
-
|
79
|
-
def instances
|
80
|
-
instances_file = File.expand_path(INSTANCES_FILE)
|
81
|
-
return nil unless File.exists? instances_file
|
82
|
-
contents = lock_and_read(instances_file).strip
|
83
|
-
JSON.parse(contents)
|
84
|
-
end
|
85
|
-
|
86
|
-
def store_instances(instances)
|
87
|
-
instances_file = File.expand_path(INSTANCES_FILE)
|
88
|
-
lock_and_write(instances_file, instances.to_json)
|
89
|
-
end
|
90
|
-
|
91
|
-
def aliases
|
92
|
-
aliases_file = File.expand_path(ALIASES_FILE)
|
93
|
-
# bacward compatible
|
94
|
-
unless File.exists? aliases_file
|
95
|
-
old_aliases_file = File.expand_path('~/.vmc-aliases')
|
96
|
-
FileUtils.mv(old_aliases_file, aliases_file) if File.exists? old_aliases_file
|
97
|
-
end
|
98
|
-
aliases = YAML.load_file(aliases_file) rescue {}
|
99
|
-
end
|
100
|
-
|
101
|
-
def store_aliases(aliases)
|
102
|
-
aliases_file = File.expand_path(ALIASES_FILE)
|
103
|
-
File.open(aliases_file, 'wb') {|f| f.write(aliases.to_yaml)}
|
104
|
-
end
|
105
|
-
|
106
|
-
def micro
|
107
|
-
micro_file = File.expand_path(MICRO_FILE)
|
108
|
-
return {} unless File.exists? micro_file
|
109
|
-
contents = lock_and_read(micro_file).strip
|
110
|
-
JSON.parse(contents)
|
111
|
-
end
|
112
|
-
|
113
|
-
def store_micro(micro)
|
114
|
-
micro_file = File.expand_path(MICRO_FILE)
|
115
|
-
lock_and_write(micro_file, micro.to_json)
|
116
|
-
end
|
117
|
-
|
118
|
-
def deep_merge(a, b)
|
119
|
-
merge = proc do |_, old, new|
|
120
|
-
if new.is_a?(Hash) and old.is_a?(Hash)
|
121
|
-
old.merge(new, &merge)
|
122
|
-
else
|
123
|
-
new
|
124
|
-
end
|
125
|
-
end
|
126
|
-
|
127
|
-
a.merge(b, &merge)
|
128
|
-
end
|
129
|
-
|
130
|
-
def clients
|
131
|
-
return @clients if @clients
|
132
|
-
|
133
|
-
stock = YAML.load_file(STOCK_CLIENTS)
|
134
|
-
clients = File.expand_path CLIENTS_FILE
|
135
|
-
if File.exists? clients
|
136
|
-
user = YAML.load_file(clients)
|
137
|
-
@clients = deep_merge(stock, user)
|
138
|
-
else
|
139
|
-
@clients = stock
|
140
|
-
end
|
141
|
-
end
|
142
|
-
|
143
|
-
def lock_and_read(file)
|
144
|
-
File.open(file, File::RDONLY) {|f|
|
145
|
-
if defined? JRUBY_VERSION
|
146
|
-
f.flock(File::LOCK_SH)
|
147
|
-
else
|
148
|
-
f.flock(File::LOCK_EX)
|
149
|
-
end
|
150
|
-
contents = f.read
|
151
|
-
f.flock(File::LOCK_UN)
|
152
|
-
contents
|
153
|
-
}
|
154
|
-
end
|
155
|
-
|
156
|
-
def lock_and_write(file, contents)
|
157
|
-
File.open(file, File::RDWR | File::CREAT, 0600) {|f|
|
158
|
-
f.flock(File::LOCK_EX)
|
159
|
-
f.rewind
|
160
|
-
f.puts contents
|
161
|
-
f.flush
|
162
|
-
f.truncate(f.pos)
|
163
|
-
f.flock(File::LOCK_UN)
|
164
|
-
}
|
165
|
-
end
|
166
|
-
end
|
167
|
-
|
168
|
-
def initialize(work_dir = Dir.pwd)
|
169
|
-
@work_dir = work_dir
|
170
|
-
end
|
171
|
-
|
172
|
-
end
|
173
|
-
end
|
@@ -1,160 +0,0 @@
|
|
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"])
|
54
|
-
lines = results.sub("Login: Password: ", "").split("\n")
|
55
|
-
last_line = lines.pop
|
56
|
-
if last_line =~ /[$%#>] \z/n
|
57
|
-
prompt = last_line
|
58
|
-
elsif last_line =~ /Login failed/
|
59
|
-
err_msg = last_line
|
60
|
-
end
|
61
|
-
break
|
62
|
-
rescue TimeoutError
|
63
|
-
sleep 1
|
64
|
-
rescue EOFError
|
65
|
-
#This may happen if we login right after app starts
|
66
|
-
close_console
|
67
|
-
sleep 5
|
68
|
-
@telnet_client = telnet_client(port)
|
69
|
-
end
|
70
|
-
display ".", false
|
71
|
-
end
|
72
|
-
unless prompt
|
73
|
-
close_console
|
74
|
-
err err_msg
|
75
|
-
end
|
76
|
-
prompt
|
77
|
-
end
|
78
|
-
|
79
|
-
def send_console_command(cmd)
|
80
|
-
results = @telnet_client.cmd(cmd)
|
81
|
-
results.split("\n")
|
82
|
-
end
|
83
|
-
|
84
|
-
def console_credentials(appname)
|
85
|
-
content = client.app_files(appname, '/app/cf-rails-console/.consoleaccess', '0')
|
86
|
-
YAML.load(content)
|
87
|
-
end
|
88
|
-
|
89
|
-
def close_console
|
90
|
-
@telnet_client.close
|
91
|
-
end
|
92
|
-
|
93
|
-
def console_tab_completion_data(cmd)
|
94
|
-
begin
|
95
|
-
results = @telnet_client.cmd("String"=> cmd + "\t", "Match"=>/\S*\n$/, "Timeout"=>10)
|
96
|
-
results.chomp.split(",")
|
97
|
-
rescue TimeoutError
|
98
|
-
[] #Just return empty results if timeout occurred on tab completion
|
99
|
-
end
|
100
|
-
end
|
101
|
-
|
102
|
-
private
|
103
|
-
def telnet_client(port)
|
104
|
-
Net::Telnet.new({"Port"=>port, "Prompt"=>/[$%#>] \z|Login failed/n, "Timeout"=>30, "FailEOF"=>true})
|
105
|
-
end
|
106
|
-
|
107
|
-
def readline_with_history(prompt)
|
108
|
-
line = Readline::readline(prompt)
|
109
|
-
return nil if line == nil || line == 'quit' || line == 'exit'
|
110
|
-
Readline::HISTORY.push(line) if not line =~ /^\s*$/ and Readline::HISTORY.to_a[-1] != line
|
111
|
-
line
|
112
|
-
end
|
113
|
-
|
114
|
-
def run_console(prompt)
|
115
|
-
prev = trap("INT") { |x| exit_console; prev.call(x); exit }
|
116
|
-
prev = trap("TERM") { |x| exit_console; prev.call(x); exit }
|
117
|
-
loop do
|
118
|
-
cmd = readline_with_history(prompt)
|
119
|
-
if(cmd == nil)
|
120
|
-
exit_console
|
121
|
-
break
|
122
|
-
end
|
123
|
-
prompt = send_console_command_display_results(cmd, prompt)
|
124
|
-
end
|
125
|
-
end
|
126
|
-
|
127
|
-
def exit_console
|
128
|
-
#TimeoutError expected, as exit doesn't return anything
|
129
|
-
@telnet_client.cmd("String"=>"exit","Timeout"=>1) rescue TimeoutError
|
130
|
-
close_console
|
131
|
-
end
|
132
|
-
|
133
|
-
def send_console_command_display_results(cmd, prompt)
|
134
|
-
begin
|
135
|
-
lines = send_console_command cmd
|
136
|
-
#Assumes the last line is a prompt
|
137
|
-
prompt = lines.pop
|
138
|
-
lines.each {|line| display line if line != cmd}
|
139
|
-
rescue TimeoutError
|
140
|
-
display "Timed out sending command to server.".red
|
141
|
-
rescue EOFError
|
142
|
-
err "The console connection has been terminated. Perhaps the app was stopped or deleted?"
|
143
|
-
end
|
144
|
-
prompt
|
145
|
-
end
|
146
|
-
|
147
|
-
def initialize_readline
|
148
|
-
if Readline.respond_to?("basic_word_break_characters=")
|
149
|
-
Readline.basic_word_break_characters= " \t\n`><=;|&{("
|
150
|
-
end
|
151
|
-
Readline.completion_append_character = nil
|
152
|
-
#Assumes that sending a String ending with tab will return a non-empty
|
153
|
-
#String of comma-separated completion options, terminated by a new line
|
154
|
-
#For example, "app.\t" might result in "to_s,nil?,etc\n"
|
155
|
-
Readline.completion_proc = proc {|s|
|
156
|
-
console_tab_completion_data s
|
157
|
-
}
|
158
|
-
end
|
159
|
-
end
|
160
|
-
end
|
data/vmc/lib/cli/core_ext.rb
DELETED
@@ -1,122 +0,0 @@
|
|
1
|
-
module VMCExtensions
|
2
|
-
|
3
|
-
def say(message)
|
4
|
-
VMC::Cli::Config.output.puts(message) if VMC::Cli::Config.output
|
5
|
-
end
|
6
|
-
|
7
|
-
def header(message, filler = '-')
|
8
|
-
say "\n"
|
9
|
-
say message
|
10
|
-
say filler.to_s * message.size
|
11
|
-
end
|
12
|
-
|
13
|
-
def banner(message)
|
14
|
-
say "\n"
|
15
|
-
say message
|
16
|
-
end
|
17
|
-
|
18
|
-
def display(message, nl=true)
|
19
|
-
if nl
|
20
|
-
say message
|
21
|
-
else
|
22
|
-
if VMC::Cli::Config.output
|
23
|
-
VMC::Cli::Config.output.print(message)
|
24
|
-
VMC::Cli::Config.output.flush
|
25
|
-
end
|
26
|
-
end
|
27
|
-
end
|
28
|
-
|
29
|
-
def clear(size=80)
|
30
|
-
return unless VMC::Cli::Config.output
|
31
|
-
VMC::Cli::Config.output.print("\r")
|
32
|
-
VMC::Cli::Config.output.print(" " * size)
|
33
|
-
VMC::Cli::Config.output.print("\r")
|
34
|
-
#VMC::Cli::Config.output.flush
|
35
|
-
end
|
36
|
-
|
37
|
-
def err(message, prefix='Error: ')
|
38
|
-
raise VMC::Cli::CliExit, "#{prefix}#{message}"
|
39
|
-
end
|
40
|
-
|
41
|
-
def warn(msg)
|
42
|
-
say "#{"[WARNING]".yellow} #{msg}"
|
43
|
-
end
|
44
|
-
|
45
|
-
def quit(message = nil)
|
46
|
-
raise VMC::Cli::GracefulExit, message
|
47
|
-
end
|
48
|
-
|
49
|
-
def blank?
|
50
|
-
self.to_s.blank?
|
51
|
-
end
|
52
|
-
|
53
|
-
def uptime_string(delta)
|
54
|
-
num_seconds = delta.to_i
|
55
|
-
days = num_seconds / (60 * 60 * 24);
|
56
|
-
num_seconds -= days * (60 * 60 * 24);
|
57
|
-
hours = num_seconds / (60 * 60);
|
58
|
-
num_seconds -= hours * (60 * 60);
|
59
|
-
minutes = num_seconds / 60;
|
60
|
-
num_seconds -= minutes * 60;
|
61
|
-
"#{days}d:#{hours}h:#{minutes}m:#{num_seconds}s"
|
62
|
-
end
|
63
|
-
|
64
|
-
def pretty_size(size, prec=1)
|
65
|
-
return 'NA' unless size
|
66
|
-
return "#{size}B" if size < 1024
|
67
|
-
return sprintf("%.#{prec}fK", size/1024.0) if size < (1024*1024)
|
68
|
-
return sprintf("%.#{prec}fM", size/(1024.0*1024.0)) if size < (1024*1024*1024)
|
69
|
-
return sprintf("%.#{prec}fG", size/(1024.0*1024.0*1024.0))
|
70
|
-
end
|
71
|
-
end
|
72
|
-
|
73
|
-
module VMCStringExtensions
|
74
|
-
|
75
|
-
def red
|
76
|
-
colorize("\e[0m\e[31m")
|
77
|
-
end
|
78
|
-
|
79
|
-
def green
|
80
|
-
colorize("\e[0m\e[32m")
|
81
|
-
end
|
82
|
-
|
83
|
-
def yellow
|
84
|
-
colorize("\e[0m\e[33m")
|
85
|
-
end
|
86
|
-
|
87
|
-
def bold
|
88
|
-
colorize("\e[0m\e[1m")
|
89
|
-
end
|
90
|
-
|
91
|
-
def colorize(color_code)
|
92
|
-
if VMC::Cli::Config.colorize
|
93
|
-
"#{color_code}#{self}\e[0m"
|
94
|
-
else
|
95
|
-
self
|
96
|
-
end
|
97
|
-
end
|
98
|
-
|
99
|
-
def blank?
|
100
|
-
self =~ /^\s*$/
|
101
|
-
end
|
102
|
-
|
103
|
-
def truncate(limit = 30)
|
104
|
-
return "" if self.blank?
|
105
|
-
etc = "..."
|
106
|
-
stripped = self.strip[0..limit]
|
107
|
-
if stripped.length > limit
|
108
|
-
stripped.gsub(/\s+?(\S+)?$/, "") + etc
|
109
|
-
else
|
110
|
-
stripped
|
111
|
-
end
|
112
|
-
end
|
113
|
-
|
114
|
-
end
|
115
|
-
|
116
|
-
class Object
|
117
|
-
include VMCExtensions
|
118
|
-
end
|
119
|
-
|
120
|
-
class String
|
121
|
-
include VMCStringExtensions
|
122
|
-
end
|
data/vmc/lib/cli/errors.rb
DELETED
@@ -1,19 +0,0 @@
|
|
1
|
-
module VMC::Cli
|
2
|
-
|
3
|
-
class CliError < StandardError
|
4
|
-
def self.error_code(code = nil)
|
5
|
-
define_method(:error_code) { code }
|
6
|
-
end
|
7
|
-
end
|
8
|
-
|
9
|
-
class UnknownCommand < CliError; error_code(100); end
|
10
|
-
class TargetMissing < CliError; error_code(102); end
|
11
|
-
class TargetInaccessible < CliError; error_code(103); end
|
12
|
-
|
13
|
-
class TargetError < CliError; error_code(201); end
|
14
|
-
class AuthError < TargetError; error_code(202); end
|
15
|
-
|
16
|
-
class CliExit < CliError; error_code(400); end
|
17
|
-
class GracefulExit < CliExit; error_code(401); end
|
18
|
-
|
19
|
-
end
|