vmc 0.4.0.beta.12 → 0.4.0.beta.13
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/bin/vmc +0 -3
- data/vmc-ng/lib/vmc.rb +5 -0
- data/vmc-ng/lib/vmc/cli.rb +190 -342
- data/vmc-ng/lib/vmc/cli/app.rb +363 -235
- data/vmc-ng/lib/vmc/cli/help.rb +12 -0
- data/vmc-ng/lib/vmc/cli/interactive.rb +101 -0
- data/vmc-ng/lib/vmc/cli/service.rb +116 -38
- data/vmc-ng/lib/vmc/cli/start.rb +252 -0
- data/vmc-ng/lib/vmc/cli/user.rb +53 -24
- data/vmc-ng/lib/vmc/plugin.rb +0 -5
- data/vmc-ng/lib/vmc/version.rb +1 -1
- metadata +16 -16
- data/vmc-ng/lib/vmc/cli/better_help.rb +0 -193
- data/vmc-ng/lib/vmc/cli/command.rb +0 -567
- data/vmc-ng/lib/vmc/cli/dots.rb +0 -190
data/vmc-ng/lib/vmc/cli/user.rb
CHANGED
@@ -1,23 +1,37 @@
|
|
1
|
-
require "vmc/cli
|
1
|
+
require "vmc/cli"
|
2
2
|
|
3
3
|
module VMC
|
4
|
-
class User <
|
5
|
-
desc "
|
4
|
+
class User < CLI
|
5
|
+
desc "List all users"
|
6
|
+
group :admin, :hidden => true
|
7
|
+
def users(input)
|
8
|
+
users =
|
9
|
+
with_progress("Getting users") do
|
10
|
+
client.users
|
11
|
+
end
|
12
|
+
|
13
|
+
users.each do |u|
|
14
|
+
display_user(u)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
|
19
|
+
desc "Create a user"
|
6
20
|
group :admin, :user, :hidden => true
|
7
|
-
|
21
|
+
input(:email, :argument => true, :desc => "User email") {
|
8
22
|
ask("Email")
|
9
23
|
}
|
10
|
-
|
24
|
+
input(:password, :desc => "User password") {
|
11
25
|
ask("Password", :echo => "*", :forget => true)
|
12
26
|
}
|
13
|
-
|
27
|
+
input(:verify, :desc => "Repeat password") {
|
14
28
|
ask("Verify Password", :echo => "*", :forget => true)
|
15
29
|
}
|
16
|
-
def
|
17
|
-
email
|
18
|
-
password = input
|
30
|
+
def create_user(input)
|
31
|
+
email = input[:email]
|
32
|
+
password = input[:password]
|
19
33
|
|
20
|
-
if !force? && password != input
|
34
|
+
if !force? && password != input[:verify]
|
21
35
|
fail "Passwords don't match."
|
22
36
|
end
|
23
37
|
|
@@ -26,36 +40,39 @@ module VMC
|
|
26
40
|
end
|
27
41
|
end
|
28
42
|
|
29
|
-
|
43
|
+
alias_command :create_user, :add_user
|
44
|
+
|
45
|
+
|
46
|
+
desc "Delete a user"
|
30
47
|
group :admin, :user, :hidden => true
|
31
|
-
|
48
|
+
input :email, :argument => true, :desc => "User to delete"
|
49
|
+
input(:really, :type => :boolean) { |email|
|
32
50
|
force? || ask("Really delete user #{c(email, :name)}?", :default => false)
|
33
51
|
}
|
34
|
-
def
|
35
|
-
return unless input
|
52
|
+
def delete_user(input)
|
53
|
+
return unless input[:really, email]
|
36
54
|
|
37
55
|
with_progress("Deleting #{c(email, :name)}") do
|
38
56
|
client.user(email).delete!
|
39
57
|
end
|
40
|
-
ensure
|
41
|
-
forget(:really)
|
42
58
|
end
|
43
59
|
|
44
|
-
|
60
|
+
|
61
|
+
desc "Update a user's password"
|
45
62
|
group :admin, :user, :hidden => true
|
46
|
-
|
63
|
+
input(:email, :argument => true, :desc => "User to update") {
|
47
64
|
ask("Email")
|
48
65
|
}
|
49
|
-
|
66
|
+
input(:password, :desc => "New password") {
|
50
67
|
ask("Password", :echo => "*", :forget => true)
|
51
68
|
}
|
52
|
-
|
69
|
+
input(:verify, :desc => "Repeat new password") {
|
53
70
|
ask("Verify Password", :echo => "*", :forget => true)
|
54
71
|
}
|
55
|
-
def passwd(
|
56
|
-
email
|
57
|
-
password = input
|
58
|
-
verify = input
|
72
|
+
def passwd(input)
|
73
|
+
email = input[:email]
|
74
|
+
password = input[:password]
|
75
|
+
verify = input[:verify]
|
59
76
|
|
60
77
|
if password != verify
|
61
78
|
fail "Passwords don't match."
|
@@ -67,5 +84,17 @@ module VMC
|
|
67
84
|
user.update!
|
68
85
|
end
|
69
86
|
end
|
87
|
+
|
88
|
+
private
|
89
|
+
|
90
|
+
def display_user(u)
|
91
|
+
if quiet?
|
92
|
+
puts u.email
|
93
|
+
else
|
94
|
+
puts ""
|
95
|
+
puts "#{c(u.email, :name)}:"
|
96
|
+
puts " admin?: #{c(u.admin?, u.admin? ? :yes : :no)}"
|
97
|
+
end
|
98
|
+
end
|
70
99
|
end
|
71
100
|
end
|
data/vmc-ng/lib/vmc/plugin.rb
CHANGED
data/vmc-ng/lib/vmc/version.rb
CHANGED
metadata
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: vmc
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 62196473
|
5
5
|
prerelease: 6
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 4
|
9
9
|
- 0
|
10
10
|
- beta
|
11
|
-
-
|
12
|
-
version: 0.4.0.beta.
|
11
|
+
- 13
|
12
|
+
version: 0.4.0.beta.13
|
13
13
|
platform: ruby
|
14
14
|
authors:
|
15
15
|
- VMware
|
@@ -17,7 +17,7 @@ autorequire:
|
|
17
17
|
bindir: bin
|
18
18
|
cert_chain: []
|
19
19
|
|
20
|
-
date: 2012-
|
20
|
+
date: 2012-07-03 00:00:00 Z
|
21
21
|
dependencies:
|
22
22
|
- !ruby/object:Gem::Dependency
|
23
23
|
name: json_pure
|
@@ -258,19 +258,19 @@ dependencies:
|
|
258
258
|
type: :runtime
|
259
259
|
version_requirements: *id014
|
260
260
|
- !ruby/object:Gem::Dependency
|
261
|
-
name:
|
261
|
+
name: mothership
|
262
262
|
prerelease: false
|
263
263
|
requirement: &id015 !ruby/object:Gem::Requirement
|
264
264
|
none: false
|
265
265
|
requirements:
|
266
266
|
- - ~>
|
267
267
|
- !ruby/object:Gem::Version
|
268
|
-
hash:
|
268
|
+
hash: 29
|
269
269
|
segments:
|
270
270
|
- 0
|
271
|
-
-
|
272
|
-
-
|
273
|
-
version: 0.
|
271
|
+
- 0
|
272
|
+
- 1
|
273
|
+
version: 0.0.1
|
274
274
|
type: :runtime
|
275
275
|
version_requirements: *id015
|
276
276
|
- !ruby/object:Gem::Dependency
|
@@ -281,12 +281,12 @@ dependencies:
|
|
281
281
|
requirements:
|
282
282
|
- - ~>
|
283
283
|
- !ruby/object:Gem::Version
|
284
|
-
hash:
|
284
|
+
hash: 19
|
285
285
|
segments:
|
286
286
|
- 0
|
287
|
-
-
|
288
|
-
-
|
289
|
-
version: 0.
|
287
|
+
- 3
|
288
|
+
- 0
|
289
|
+
version: 0.3.0
|
290
290
|
type: :runtime
|
291
291
|
version_requirements: *id016
|
292
292
|
description:
|
@@ -343,10 +343,10 @@ files:
|
|
343
343
|
- vmc-ng/LICENSE
|
344
344
|
- vmc-ng/Rakefile
|
345
345
|
- vmc-ng/lib/vmc/cli/app.rb
|
346
|
-
- vmc-ng/lib/vmc/cli/
|
347
|
-
- vmc-ng/lib/vmc/cli/
|
348
|
-
- vmc-ng/lib/vmc/cli/dots.rb
|
346
|
+
- vmc-ng/lib/vmc/cli/help.rb
|
347
|
+
- vmc-ng/lib/vmc/cli/interactive.rb
|
349
348
|
- vmc-ng/lib/vmc/cli/service.rb
|
349
|
+
- vmc-ng/lib/vmc/cli/start.rb
|
350
350
|
- vmc-ng/lib/vmc/cli/user.rb
|
351
351
|
- vmc-ng/lib/vmc/cli.rb
|
352
352
|
- vmc-ng/lib/vmc/constants.rb
|
@@ -1,193 +0,0 @@
|
|
1
|
-
module VMC
|
2
|
-
module BetterHelp
|
3
|
-
@@groups = []
|
4
|
-
@@tree = {}
|
5
|
-
|
6
|
-
def nothing_printable?(group, all = false)
|
7
|
-
group[:members].reject { |_, _, opts| !all && opts[:hidden] }.empty? &&
|
8
|
-
group[:children].all? { |g| nothing_printable?(g) }
|
9
|
-
end
|
10
|
-
|
11
|
-
def print_help_group(group, all = false, indent = 0)
|
12
|
-
return if nothing_printable?(group, all)
|
13
|
-
|
14
|
-
members = group[:members]
|
15
|
-
|
16
|
-
unless all
|
17
|
-
members = members.reject do |_, _, opts|
|
18
|
-
opts[:hidden]
|
19
|
-
end
|
20
|
-
end
|
21
|
-
|
22
|
-
members = members.collect do |cls, name, opts|
|
23
|
-
[cls, cls.tasks[name]]
|
24
|
-
end
|
25
|
-
|
26
|
-
i = " " * indent
|
27
|
-
|
28
|
-
print i
|
29
|
-
puts group[:description]
|
30
|
-
|
31
|
-
width = 0
|
32
|
-
members.each do |cls, t|
|
33
|
-
sub = find_subcommand_name(cls)
|
34
|
-
len = (sub ? sub.size + 1 : 0) + t.usage.size
|
35
|
-
if len > width
|
36
|
-
width = len
|
37
|
-
end
|
38
|
-
end
|
39
|
-
|
40
|
-
members.each do |cls, t|
|
41
|
-
sub = find_subcommand_name(cls)
|
42
|
-
|
43
|
-
print "#{i} "
|
44
|
-
|
45
|
-
label = sub ? "#{sub} " : ""
|
46
|
-
label << t.usage
|
47
|
-
|
48
|
-
print "#{label.ljust(width)}\t#{t.description}"
|
49
|
-
|
50
|
-
puts ""
|
51
|
-
end
|
52
|
-
|
53
|
-
puts "" unless members.empty?
|
54
|
-
|
55
|
-
group[:children].each do |group|
|
56
|
-
print_help_group(group, all, indent + 1)
|
57
|
-
end
|
58
|
-
end
|
59
|
-
|
60
|
-
def groups(*tree)
|
61
|
-
tree.each do |*args|
|
62
|
-
add_group(@@groups, @@tree, *args.first)
|
63
|
-
end
|
64
|
-
end
|
65
|
-
|
66
|
-
def add_group(groups, tree, name, desc, *subs)
|
67
|
-
members = []
|
68
|
-
|
69
|
-
meta = {:members => members, :children => []}
|
70
|
-
groups << meta
|
71
|
-
|
72
|
-
tree[name] = {:members => members, :children => {}}
|
73
|
-
|
74
|
-
meta[:description] = desc
|
75
|
-
|
76
|
-
subs.each do |*args|
|
77
|
-
add_group(meta[:children], tree[name][:children], *args.first)
|
78
|
-
end
|
79
|
-
end
|
80
|
-
|
81
|
-
def group(*names)
|
82
|
-
options =
|
83
|
-
if names.last.is_a? Hash
|
84
|
-
names.pop
|
85
|
-
else
|
86
|
-
{}
|
87
|
-
end
|
88
|
-
|
89
|
-
where = @@tree
|
90
|
-
top = true
|
91
|
-
names.each do |n|
|
92
|
-
where = where[:children] unless top
|
93
|
-
|
94
|
-
unless where
|
95
|
-
raise "unknown group: #{names.join("/")}"
|
96
|
-
end
|
97
|
-
|
98
|
-
where = where[n]
|
99
|
-
|
100
|
-
top = false
|
101
|
-
end
|
102
|
-
|
103
|
-
where[:members] << [self, @usage.split.first, options]
|
104
|
-
end
|
105
|
-
|
106
|
-
def subcommand_classes
|
107
|
-
@subcommand_classes ||= {}
|
108
|
-
end
|
109
|
-
|
110
|
-
def subcommand_names
|
111
|
-
@subcommand_names ||= {}
|
112
|
-
end
|
113
|
-
|
114
|
-
def subcommand(name, cls)
|
115
|
-
subcommand_classes[name] = cls
|
116
|
-
subcommand_names[cls] = name
|
117
|
-
super
|
118
|
-
end
|
119
|
-
|
120
|
-
def find_subcommand_name(cls)
|
121
|
-
found = subcommand_names[cls]
|
122
|
-
return found if found
|
123
|
-
|
124
|
-
if superclass.respond_to?(:find_subcommand_name) &&
|
125
|
-
found = superclass.find_subcommand_name(cls)
|
126
|
-
return found
|
127
|
-
end
|
128
|
-
|
129
|
-
subcommand_classes.each do |name, sub|
|
130
|
-
if found = sub.find_subcommand_name(cls)
|
131
|
-
return name + " " + found
|
132
|
-
end
|
133
|
-
end
|
134
|
-
|
135
|
-
nil
|
136
|
-
end
|
137
|
-
|
138
|
-
def find_subcommand(name)
|
139
|
-
found = subcommand_classes[name]
|
140
|
-
return found if found
|
141
|
-
|
142
|
-
if superclass.respond_to? :find_subcommand
|
143
|
-
superclass.find_subcommand(name)
|
144
|
-
else
|
145
|
-
nil
|
146
|
-
end
|
147
|
-
end
|
148
|
-
|
149
|
-
def task_help(shell, task_name)
|
150
|
-
if sub = find_subcommand(task_name)
|
151
|
-
sub.help(shell, true)
|
152
|
-
elsif t = all_tasks[task_name]
|
153
|
-
puts t.description
|
154
|
-
puts ""
|
155
|
-
puts "Usage: #{t.usage}"
|
156
|
-
puts ""
|
157
|
-
class_options_help(shell, nil => t.options.map { |_, o| o })
|
158
|
-
else
|
159
|
-
super
|
160
|
-
end
|
161
|
-
end
|
162
|
-
|
163
|
-
def help(shell, subcommand = false)
|
164
|
-
puts "Tasks:"
|
165
|
-
|
166
|
-
width = 0
|
167
|
-
@tasks.each do |_, t|
|
168
|
-
len = t.usage.size
|
169
|
-
if len > width
|
170
|
-
width = len
|
171
|
-
end
|
172
|
-
end
|
173
|
-
|
174
|
-
@tasks.each do |_, t|
|
175
|
-
print " "
|
176
|
-
|
177
|
-
print "#{t.usage.ljust(width)}\t#{t.description}"
|
178
|
-
|
179
|
-
puts ""
|
180
|
-
end
|
181
|
-
|
182
|
-
puts ""
|
183
|
-
|
184
|
-
class_options_help(shell)
|
185
|
-
end
|
186
|
-
|
187
|
-
def print_help_groups(all = false)
|
188
|
-
@@groups.each do |commands|
|
189
|
-
print_help_group(commands, all)
|
190
|
-
end
|
191
|
-
end
|
192
|
-
end
|
193
|
-
end
|
@@ -1,567 +0,0 @@
|
|
1
|
-
require "thor"
|
2
|
-
require "interact"
|
3
|
-
require "yaml"
|
4
|
-
|
5
|
-
require "cfoundry"
|
6
|
-
|
7
|
-
require "vmc/constants"
|
8
|
-
require "vmc/errors"
|
9
|
-
require "vmc/cli/dots"
|
10
|
-
require "vmc/cli/better_help"
|
11
|
-
|
12
|
-
|
13
|
-
$vmc_asked_auth = false
|
14
|
-
|
15
|
-
module VMC
|
16
|
-
module Interactive
|
17
|
-
include ::Interactive::Rewindable
|
18
|
-
include Dots
|
19
|
-
|
20
|
-
class InteractiveDefault
|
21
|
-
attr_reader :method
|
22
|
-
|
23
|
-
def initialize(query, cls, cmd, flag)
|
24
|
-
# here be dragons
|
25
|
-
#
|
26
|
-
# MRI has no Proc -> Lambda, so this is kind of the only way to work
|
27
|
-
# around Proc's "convenient" argument handling while keeping the
|
28
|
-
# blocks evaluated on the Command instance
|
29
|
-
|
30
|
-
@method = :"__interact_#{cmd}_#{flag}__"
|
31
|
-
cls.queries.send(:define_method, @method, &query)
|
32
|
-
end
|
33
|
-
|
34
|
-
def to_s
|
35
|
-
"(interaction)"
|
36
|
-
end
|
37
|
-
end
|
38
|
-
|
39
|
-
def force?
|
40
|
-
false
|
41
|
-
end
|
42
|
-
|
43
|
-
def ask(question, options = {})
|
44
|
-
if force? and options.key?(:default)
|
45
|
-
options[:default]
|
46
|
-
else
|
47
|
-
super
|
48
|
-
end
|
49
|
-
end
|
50
|
-
|
51
|
-
def list_choices(choices, options)
|
52
|
-
choices.each_with_index do |o, i|
|
53
|
-
puts "#{c(i + 1, :number)}: #{o}"
|
54
|
-
end
|
55
|
-
end
|
56
|
-
|
57
|
-
def input_state(options)
|
58
|
-
CFState.new(options)
|
59
|
-
end
|
60
|
-
|
61
|
-
def prompt(question, options)
|
62
|
-
value =
|
63
|
-
case options[:default]
|
64
|
-
when true
|
65
|
-
"y"
|
66
|
-
when false
|
67
|
-
"n"
|
68
|
-
when nil
|
69
|
-
""
|
70
|
-
else
|
71
|
-
options[:default].to_s
|
72
|
-
end
|
73
|
-
|
74
|
-
print "#{question}"
|
75
|
-
print c("> ", :prompt)
|
76
|
-
|
77
|
-
unless value.empty?
|
78
|
-
print "#{c(value, :default) + "\b" * value.size}"
|
79
|
-
end
|
80
|
-
end
|
81
|
-
|
82
|
-
def handler(which, state)
|
83
|
-
ans = state.answer
|
84
|
-
pos = state.position
|
85
|
-
|
86
|
-
if state.default?
|
87
|
-
if which.is_a?(Array) and which[0] == :key
|
88
|
-
# initial non-movement keypress clears default answer
|
89
|
-
clear_input(state)
|
90
|
-
else
|
91
|
-
# wipe away any coloring
|
92
|
-
redraw_input(state)
|
93
|
-
end
|
94
|
-
|
95
|
-
state.clear_default!
|
96
|
-
end
|
97
|
-
|
98
|
-
super
|
99
|
-
|
100
|
-
print "\n" if which == :enter
|
101
|
-
end
|
102
|
-
|
103
|
-
class CFState < Interactive::InputState
|
104
|
-
def initialize(options = {}, answer = nil, position = 0)
|
105
|
-
@options = options
|
106
|
-
|
107
|
-
if answer
|
108
|
-
@answer = answer
|
109
|
-
elsif options[:default]
|
110
|
-
case options[:default]
|
111
|
-
when true
|
112
|
-
@answer = "y"
|
113
|
-
when false
|
114
|
-
@answer = "n"
|
115
|
-
else
|
116
|
-
@answer = options[:default].to_s
|
117
|
-
end
|
118
|
-
|
119
|
-
@default = true
|
120
|
-
else
|
121
|
-
@answer = ""
|
122
|
-
end
|
123
|
-
|
124
|
-
@position = position
|
125
|
-
@done = false
|
126
|
-
end
|
127
|
-
|
128
|
-
def clear_default!
|
129
|
-
@default = false
|
130
|
-
end
|
131
|
-
|
132
|
-
def default?
|
133
|
-
@default
|
134
|
-
end
|
135
|
-
end
|
136
|
-
end
|
137
|
-
|
138
|
-
class Command < Thor
|
139
|
-
include Interactive
|
140
|
-
extend BetterHelp
|
141
|
-
|
142
|
-
class_option :proxy, :aliases => "-u", :desc => "Proxy user"
|
143
|
-
|
144
|
-
class_option :version,
|
145
|
-
:type => :boolean, :aliases => "-v", :desc => "Print version number"
|
146
|
-
|
147
|
-
class_option :verbose, :type => :boolean, :desc => "Verbose"
|
148
|
-
|
149
|
-
class_option :force,
|
150
|
-
:type => :boolean, :aliases => "-f", :desc => "Force (no interaction)"
|
151
|
-
|
152
|
-
class_option :simple_output,
|
153
|
-
:type => :boolean, :desc => "Simplified output format."
|
154
|
-
|
155
|
-
class_option :script, :type => :boolean, :aliases => "-s",
|
156
|
-
:desc => "--simple-output and --force"
|
157
|
-
|
158
|
-
class_option :trace, :type => :boolean, :aliases => "-t",
|
159
|
-
:desc => "Show API requests and responses"
|
160
|
-
|
161
|
-
class_option :color, :type => :boolean, :desc => "Colored output"
|
162
|
-
|
163
|
-
def self.queries
|
164
|
-
return @queries if @queries
|
165
|
-
|
166
|
-
@queries = Module.new
|
167
|
-
include @queries
|
168
|
-
|
169
|
-
@queries
|
170
|
-
end
|
171
|
-
|
172
|
-
def self.flag(name, options = {}, &query)
|
173
|
-
if query
|
174
|
-
options[:default] ||=
|
175
|
-
InteractiveDefault.new(query, self, @usage.split.first, name)
|
176
|
-
end
|
177
|
-
|
178
|
-
method_option(name, options)
|
179
|
-
end
|
180
|
-
|
181
|
-
def self.callbacks_for(name)
|
182
|
-
cs = callbacks[name]
|
183
|
-
if superclass.respond_to? :callbacks
|
184
|
-
cs.merge superclass.callbacks_for(name)
|
185
|
-
else
|
186
|
-
cs
|
187
|
-
end
|
188
|
-
end
|
189
|
-
|
190
|
-
def self.callbacks
|
191
|
-
@callbacks ||= Hash.new do |h, name|
|
192
|
-
h[name] = Hash.new do |h, task|
|
193
|
-
h[task] = []
|
194
|
-
end
|
195
|
-
end
|
196
|
-
end
|
197
|
-
|
198
|
-
def self.add_callback(name, task, callback)
|
199
|
-
callbacks[name][task] << callback
|
200
|
-
end
|
201
|
-
|
202
|
-
def self.before(task, &callback)
|
203
|
-
add_callback(:before, task, callback)
|
204
|
-
end
|
205
|
-
|
206
|
-
def self.after(task, &callback)
|
207
|
-
add_callback(:after, task, callback)
|
208
|
-
end
|
209
|
-
|
210
|
-
def self.ensuring(task, &callback)
|
211
|
-
add_callback(:ensuring, task, callback)
|
212
|
-
end
|
213
|
-
|
214
|
-
def self.around(task, &callback)
|
215
|
-
add_callback(:around, task, callback)
|
216
|
-
end
|
217
|
-
|
218
|
-
def self.filter(task, &callback)
|
219
|
-
add_callback(:filter, task, callback)
|
220
|
-
end
|
221
|
-
|
222
|
-
private
|
223
|
-
|
224
|
-
def callbacks_for(what)
|
225
|
-
self.class.callbacks_for(what)
|
226
|
-
end
|
227
|
-
|
228
|
-
def passed_value(flag)
|
229
|
-
if (val = inputs[flag] || options[flag]) && \
|
230
|
-
!val.is_a?(VMC::Interactive::InteractiveDefault)
|
231
|
-
val
|
232
|
-
end
|
233
|
-
end
|
234
|
-
|
235
|
-
def inputs
|
236
|
-
@inputs ||= {}
|
237
|
-
end
|
238
|
-
|
239
|
-
def input(name, *args)
|
240
|
-
return inputs[name] if inputs.key?(name)
|
241
|
-
|
242
|
-
val = options[name]
|
243
|
-
inputs[name] =
|
244
|
-
if val.is_a?(VMC::Interactive::InteractiveDefault)
|
245
|
-
send(val.method, *args)
|
246
|
-
elsif val.respond_to? :to_proc
|
247
|
-
instance_exec(*args, &options[name])
|
248
|
-
else
|
249
|
-
options[name]
|
250
|
-
end
|
251
|
-
end
|
252
|
-
|
253
|
-
def forget(name)
|
254
|
-
@inputs.delete name
|
255
|
-
end
|
256
|
-
|
257
|
-
def script?
|
258
|
-
if options.key?("script")
|
259
|
-
options["script"]
|
260
|
-
else
|
261
|
-
!$stdout.tty?
|
262
|
-
end
|
263
|
-
end
|
264
|
-
|
265
|
-
def force?
|
266
|
-
if options.key?("force")
|
267
|
-
options["force"]
|
268
|
-
else
|
269
|
-
script?
|
270
|
-
end
|
271
|
-
end
|
272
|
-
|
273
|
-
def verbose?
|
274
|
-
options["verbose"]
|
275
|
-
end
|
276
|
-
|
277
|
-
def simple_output?
|
278
|
-
if options.key?("simple_output")
|
279
|
-
options["simple_output"]
|
280
|
-
else
|
281
|
-
script?
|
282
|
-
end
|
283
|
-
end
|
284
|
-
|
285
|
-
def color?
|
286
|
-
if options.key?("color")
|
287
|
-
options["color"]
|
288
|
-
else
|
289
|
-
!simple_output?
|
290
|
-
end
|
291
|
-
end
|
292
|
-
|
293
|
-
def err(msg, exit_status = 1)
|
294
|
-
if script?
|
295
|
-
$stderr.puts(msg)
|
296
|
-
else
|
297
|
-
puts c(msg, :error)
|
298
|
-
end
|
299
|
-
|
300
|
-
$exit_status = 1
|
301
|
-
end
|
302
|
-
|
303
|
-
def with_filters(new)
|
304
|
-
new.each do |task, callback|
|
305
|
-
self.class.callbacks[:filter][task] << callback
|
306
|
-
end
|
307
|
-
|
308
|
-
yield
|
309
|
-
ensure
|
310
|
-
new.each do |task, _|
|
311
|
-
self.class.callbacks[:filter][task].pop
|
312
|
-
end
|
313
|
-
end
|
314
|
-
|
315
|
-
def with_inputs(new)
|
316
|
-
return yield if !new || new.empty?
|
317
|
-
|
318
|
-
begin
|
319
|
-
orig = {}
|
320
|
-
new.each do |k, v|
|
321
|
-
orig[k] = inputs[k]
|
322
|
-
inputs[k] = v
|
323
|
-
end
|
324
|
-
|
325
|
-
yield
|
326
|
-
ensure
|
327
|
-
orig.each do |k, v|
|
328
|
-
if v.nil?
|
329
|
-
inputs.delete(k)
|
330
|
-
else
|
331
|
-
inputs[k] = v
|
332
|
-
end
|
333
|
-
end
|
334
|
-
end
|
335
|
-
end
|
336
|
-
|
337
|
-
def fail(msg)
|
338
|
-
raise UserError, msg
|
339
|
-
end
|
340
|
-
|
341
|
-
def filter(name, val)
|
342
|
-
callbacks_for(:filter)[name].each do |f|
|
343
|
-
val = f.call val
|
344
|
-
end
|
345
|
-
|
346
|
-
val
|
347
|
-
end
|
348
|
-
|
349
|
-
def invoke_task(task, args)
|
350
|
-
callbacks_for(:before)[task.name.to_sym].each do |c|
|
351
|
-
c.call
|
352
|
-
end
|
353
|
-
|
354
|
-
action = proc do |*given_args|
|
355
|
-
if inputs = given_args.first
|
356
|
-
with_inputs(inputs) do
|
357
|
-
task.run(self, args)
|
358
|
-
end
|
359
|
-
else
|
360
|
-
task.run(self, args)
|
361
|
-
end
|
362
|
-
end
|
363
|
-
|
364
|
-
callbacks_for(:around)[task.name.to_sym].each do |a|
|
365
|
-
before = action
|
366
|
-
action = proc do |*given_args|
|
367
|
-
if inputs = given_args.first
|
368
|
-
with_inputs(inputs) do
|
369
|
-
instance_exec(before, args, &a)
|
370
|
-
end
|
371
|
-
else
|
372
|
-
instance_exec(before, args, &a)
|
373
|
-
end
|
374
|
-
end
|
375
|
-
end
|
376
|
-
|
377
|
-
res = instance_exec(args, &action)
|
378
|
-
|
379
|
-
callbacks_for(:after)[task.name.to_sym].each do |c|
|
380
|
-
c.call
|
381
|
-
end
|
382
|
-
|
383
|
-
res
|
384
|
-
rescue Interrupt
|
385
|
-
$exit_status = 130
|
386
|
-
rescue Thor::Error
|
387
|
-
raise
|
388
|
-
rescue UserError => e
|
389
|
-
err e.message
|
390
|
-
rescue CFoundry::Denied => e
|
391
|
-
if !$vmc_asked_auth && e.error_code == 200
|
392
|
-
$vmc_asked_auth = true
|
393
|
-
|
394
|
-
puts ""
|
395
|
-
puts c("Not authenticated! Try logging in:", :warning)
|
396
|
-
|
397
|
-
invoke :login
|
398
|
-
@client = nil
|
399
|
-
|
400
|
-
retry
|
401
|
-
end
|
402
|
-
|
403
|
-
err "Denied: #{e.description}"
|
404
|
-
rescue Exception => e
|
405
|
-
msg = e.class.name
|
406
|
-
msg << ": #{e}" unless e.to_s.empty?
|
407
|
-
err msg
|
408
|
-
|
409
|
-
ensure_config_dir
|
410
|
-
|
411
|
-
File.open(File.expand_path(VMC::CRASH_FILE), "w") do |f|
|
412
|
-
f.print "Time of crash:\n "
|
413
|
-
f.puts Time.now
|
414
|
-
f.puts ""
|
415
|
-
f.puts msg
|
416
|
-
f.puts ""
|
417
|
-
|
418
|
-
e.backtrace.each do |loc|
|
419
|
-
if loc =~ /\/gems\//
|
420
|
-
f.puts loc.sub(/.*\/gems\//, "")
|
421
|
-
else
|
422
|
-
f.puts loc.sub(File.expand_path("../../../..", __FILE__) + "/", "")
|
423
|
-
end
|
424
|
-
end
|
425
|
-
end
|
426
|
-
ensure
|
427
|
-
callbacks_for(:ensuring)[task.name.to_sym].each do |c|
|
428
|
-
c.call
|
429
|
-
end
|
430
|
-
end
|
431
|
-
public :invoke_task
|
432
|
-
|
433
|
-
def sane_target_url(url)
|
434
|
-
unless url =~ /^https?:\/\//
|
435
|
-
url = "http://#{url}"
|
436
|
-
end
|
437
|
-
|
438
|
-
url.gsub(/\/$/, "")
|
439
|
-
end
|
440
|
-
|
441
|
-
def target_file
|
442
|
-
one_of(VMC::TARGET_FILE, VMC::OLD_TARGET_FILE)
|
443
|
-
end
|
444
|
-
|
445
|
-
def tokens_file
|
446
|
-
one_of(VMC::TOKENS_FILE, VMC::OLD_TOKENS_FILE)
|
447
|
-
end
|
448
|
-
|
449
|
-
def one_of(*paths)
|
450
|
-
paths.each do |p|
|
451
|
-
exp = File.expand_path(p)
|
452
|
-
return exp if File.exist? exp
|
453
|
-
end
|
454
|
-
|
455
|
-
paths.first
|
456
|
-
end
|
457
|
-
|
458
|
-
def client_target
|
459
|
-
File.read(target_file).chomp
|
460
|
-
end
|
461
|
-
|
462
|
-
def ensure_config_dir
|
463
|
-
config = File.expand_path(VMC::CONFIG_DIR)
|
464
|
-
Dir.mkdir(config) unless File.exist? config
|
465
|
-
end
|
466
|
-
|
467
|
-
def set_target(url)
|
468
|
-
ensure_config_dir
|
469
|
-
|
470
|
-
File.open(File.expand_path(VMC::TARGET_FILE), "w") do |f|
|
471
|
-
f.write(sane_target_url(url))
|
472
|
-
end
|
473
|
-
|
474
|
-
@client = nil
|
475
|
-
end
|
476
|
-
|
477
|
-
def tokens
|
478
|
-
new_toks = File.expand_path(VMC::TOKENS_FILE)
|
479
|
-
old_toks = File.expand_path(VMC::OLD_TOKENS_FILE)
|
480
|
-
|
481
|
-
if File.exist? new_toks
|
482
|
-
YAML.load_file(new_toks)
|
483
|
-
elsif File.exist? old_toks
|
484
|
-
JSON.load(File.read(old_toks))
|
485
|
-
else
|
486
|
-
{}
|
487
|
-
end
|
488
|
-
end
|
489
|
-
|
490
|
-
def client_token
|
491
|
-
tokens[client_target]
|
492
|
-
end
|
493
|
-
|
494
|
-
def save_tokens(ts)
|
495
|
-
ensure_config_dir
|
496
|
-
|
497
|
-
File.open(File.expand_path(VMC::TOKENS_FILE), "w") do |io|
|
498
|
-
YAML.dump(ts, io)
|
499
|
-
end
|
500
|
-
end
|
501
|
-
|
502
|
-
def save_token(token)
|
503
|
-
ts = tokens
|
504
|
-
ts[client_target] = token
|
505
|
-
save_tokens(ts)
|
506
|
-
end
|
507
|
-
|
508
|
-
def remove_token
|
509
|
-
ts = tokens
|
510
|
-
ts.delete client_target
|
511
|
-
save_tokens(ts)
|
512
|
-
end
|
513
|
-
|
514
|
-
def client
|
515
|
-
return @client if @client
|
516
|
-
|
517
|
-
@client = CFoundry::Client.new(client_target, client_token)
|
518
|
-
@client.proxy = options[:proxy]
|
519
|
-
@client.trace = options[:trace]
|
520
|
-
@client
|
521
|
-
end
|
522
|
-
|
523
|
-
def usage(used, limit)
|
524
|
-
"#{b(human_size(used))} of #{b(human_size(limit, 0))}"
|
525
|
-
end
|
526
|
-
|
527
|
-
def percentage(num, low = 50, mid = 70)
|
528
|
-
color =
|
529
|
-
if num <= low
|
530
|
-
:good
|
531
|
-
elsif num <= mid
|
532
|
-
:warning
|
533
|
-
else
|
534
|
-
:bad
|
535
|
-
end
|
536
|
-
|
537
|
-
c(format("%.1f\%", num), color)
|
538
|
-
end
|
539
|
-
|
540
|
-
def megabytes(str)
|
541
|
-
if str =~ /T$/i
|
542
|
-
str.to_i * 1024 * 1024
|
543
|
-
elsif str =~ /G$/i
|
544
|
-
str.to_i * 1024
|
545
|
-
elsif str =~ /M$/i
|
546
|
-
str.to_i
|
547
|
-
elsif str =~ /K$/i
|
548
|
-
str.to_i / 1024
|
549
|
-
else # assume megabytes
|
550
|
-
str.to_i
|
551
|
-
end
|
552
|
-
end
|
553
|
-
|
554
|
-
def human_size(num, precision = 1)
|
555
|
-
sizes = ["G", "M", "K"]
|
556
|
-
sizes.each.with_index do |suf, i|
|
557
|
-
pow = sizes.size - i
|
558
|
-
unit = 1024 ** pow
|
559
|
-
if num >= unit
|
560
|
-
return format("%.#{precision}f%s", num / unit, suf)
|
561
|
-
end
|
562
|
-
end
|
563
|
-
|
564
|
-
format("%.#{precision}fB", num)
|
565
|
-
end
|
566
|
-
end
|
567
|
-
end
|