vmc 0.4.2 → 0.4.3
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/vmc.rb +2 -5
- data/lib/vmc/cli/app/apps.rb +4 -1
- data/lib/vmc/cli/app/push.rb +38 -221
- data/lib/vmc/cli/app/push/create.rb +125 -0
- data/lib/vmc/cli/app/push/interaction.rb +64 -0
- data/lib/vmc/cli/app/push/sync.rb +59 -0
- data/lib/vmc/cli/app/rename.rb +1 -1
- data/lib/vmc/cli/organization/base.rb +14 -0
- data/lib/vmc/cli/organization/create_org.rb +28 -0
- data/lib/vmc/cli/organization/delete_org.rb +65 -0
- data/lib/vmc/cli/organization/org.rb +46 -0
- data/lib/vmc/cli/organization/orgs.rb +35 -0
- data/lib/vmc/cli/organization/rename.rb +32 -0
- data/lib/vmc/cli/service/base.rb +8 -0
- data/lib/vmc/cli/service/binding.rb +66 -0
- data/lib/vmc/cli/service/create.rb +104 -0
- data/lib/vmc/cli/service/delete.rb +84 -0
- data/lib/vmc/cli/service/rename.rb +32 -0
- data/lib/vmc/cli/service/service.rb +45 -0
- data/lib/vmc/cli/service/services.rb +118 -0
- data/lib/vmc/cli/space/base.rb +21 -0
- data/lib/vmc/cli/space/create.rb +57 -0
- data/lib/vmc/cli/space/delete.rb +92 -0
- data/lib/vmc/cli/space/rename.rb +36 -0
- data/lib/vmc/cli/space/space.rb +67 -0
- data/lib/vmc/cli/space/spaces.rb +57 -0
- data/lib/vmc/cli/space/take.rb +18 -0
- data/lib/vmc/cli/start/base.rb +100 -0
- data/lib/vmc/cli/start/colors.rb +14 -0
- data/lib/vmc/cli/start/info.rb +124 -0
- data/lib/vmc/cli/start/login.rb +94 -0
- data/lib/vmc/cli/start/logout.rb +14 -0
- data/lib/vmc/cli/start/register.rb +38 -0
- data/lib/vmc/cli/start/target.rb +68 -0
- data/lib/vmc/cli/start/targets.rb +17 -0
- data/lib/vmc/version.rb +1 -1
- data/spec/factories/app_factory.rb +5 -0
- data/spec/factories/client_factory.rb +10 -1
- data/spec/factories/domain_factory.rb +2 -1
- data/spec/factories/factory.rb +1 -0
- data/spec/factories/framework_factory.rb +1 -0
- data/spec/factories/organization_factory.rb +18 -0
- data/spec/factories/route_factory.rb +1 -0
- data/spec/factories/runtime_factory.rb +10 -0
- data/spec/factories/service_binding_factory.rb +9 -0
- data/spec/factories/service_factory.rb +17 -0
- data/spec/factories/service_instance_factory.rb +10 -0
- data/spec/factories/service_plan_factory.rb +11 -0
- data/spec/factories/space_factory.rb +10 -0
- data/spec/support/interact_helpers.rb +7 -3
- data/spec/vmc/cli/app/push/create_spec.rb +450 -0
- data/spec/vmc/cli/app/push_spec.rb +303 -9
- data/spec/vmc/cli/app/rename_spec.rb +9 -4
- data/spec/vmc/cli/organization/rename_spec.rb +113 -0
- data/spec/vmc/cli/route/delete_route_spec.rb +2 -2
- data/spec/vmc/cli/service/rename_spec.rb +114 -0
- data/spec/vmc/cli/space/rename_spec.rb +114 -0
- metadata +109 -64
- data/lib/vmc/cli/organization.rb +0 -176
- data/lib/vmc/cli/service.rb +0 -387
- data/lib/vmc/cli/space.rb +0 -284
- data/lib/vmc/cli/start.rb +0 -432
- data/spec/assets/hello-sinatra/Gemfile.lock +0 -17
data/lib/vmc.rb
CHANGED
@@ -1,12 +1,9 @@
|
|
1
1
|
require "vmc/version"
|
2
2
|
|
3
3
|
require "vmc/cli"
|
4
|
-
require "vmc/cli/start"
|
5
|
-
require "vmc/cli/service"
|
6
4
|
require "vmc/cli/user"
|
7
|
-
require "vmc/cli/space"
|
8
|
-
require "vmc/cli/organization"
|
9
5
|
|
10
|
-
|
6
|
+
command_files = "../vmc/cli/{app,route,domain,organization,space,service,start}/*.rb"
|
7
|
+
Dir[File.expand_path(command_files, __FILE__)].each do |file|
|
11
8
|
require file unless File.basename(file) == 'base.rb'
|
12
9
|
end
|
data/lib/vmc/cli/app/apps.rb
CHANGED
@@ -15,7 +15,10 @@ module VMC::App
|
|
15
15
|
:desc => "Verbose output format"
|
16
16
|
def apps
|
17
17
|
if space = input[:space]
|
18
|
-
|
18
|
+
begin
|
19
|
+
space.summarize!
|
20
|
+
rescue CFoundry::APIError
|
21
|
+
end
|
19
22
|
|
20
23
|
apps =
|
21
24
|
with_progress("Getting applications in #{c(space.name, :name)}") do
|
data/lib/vmc/cli/app/push.rb
CHANGED
@@ -1,9 +1,13 @@
|
|
1
1
|
require "vmc/detect"
|
2
|
-
|
3
2
|
require "vmc/cli/app/base"
|
3
|
+
require "vmc/cli/app/push/sync"
|
4
|
+
require "vmc/cli/app/push/create"
|
4
5
|
|
5
6
|
module VMC::App
|
6
7
|
class Push < Base
|
8
|
+
include Sync
|
9
|
+
include Create
|
10
|
+
|
7
11
|
desc "Push an application, syncing changes if it exists"
|
8
12
|
group :apps, :manage
|
9
13
|
input(:name, :argument => true, :desc => "Application name") {
|
@@ -37,13 +41,13 @@ module VMC::App
|
|
37
41
|
:desc => "Number of instances to run") {
|
38
42
|
ask("Instances", :default => 1)
|
39
43
|
}
|
40
|
-
input(:framework, :from_given =>
|
41
|
-
:desc => "Framework to use") { |
|
42
|
-
ask_with_other("Framework",
|
44
|
+
input(:framework, :from_given => by_name("framework"),
|
45
|
+
:desc => "Framework to use") { |choices, default, other|
|
46
|
+
ask_with_other("Framework", client.frameworks, choices, default, other)
|
43
47
|
}
|
44
|
-
input(:runtime, :from_given =>
|
45
|
-
:desc => "Runtime to use") { |
|
46
|
-
ask_with_other("Runtime",
|
48
|
+
input(:runtime, :from_given => by_name("runtime"),
|
49
|
+
:desc => "Runtime to use") { |choices, default, other|
|
50
|
+
ask_with_other("Runtime", client.runtimes, choices, default, other)
|
47
51
|
}
|
48
52
|
input(:command, :desc => "Startup command for standalone app") {
|
49
53
|
ask("Startup command")
|
@@ -55,242 +59,50 @@ module VMC::App
|
|
55
59
|
input :restart, :type => :boolean, :default => true,
|
56
60
|
:desc => "Restart app after updating?"
|
57
61
|
input(:create_services, :type => :boolean,
|
62
|
+
:default => proc { force? ? false : interact },
|
58
63
|
:desc => "Interactively create services?") {
|
59
64
|
line unless quiet?
|
60
65
|
ask "Create services for application?", :default => false
|
61
66
|
}
|
62
67
|
input(:bind_services, :type => :boolean,
|
68
|
+
:default => proc { force? ? false : interact },
|
63
69
|
:desc => "Interactively bind services?") {
|
64
|
-
|
70
|
+
unless all_instances.empty?
|
71
|
+
ask "Bind other services to application?", :default => false
|
72
|
+
end
|
65
73
|
}
|
66
74
|
def push
|
67
75
|
name = input[:name]
|
68
76
|
path = File.expand_path(input[:path])
|
77
|
+
app = client.app_by_name(name)
|
69
78
|
|
70
|
-
if app
|
79
|
+
if app
|
71
80
|
sync_app(app, path)
|
72
81
|
else
|
73
|
-
|
82
|
+
setup_new_app(path)
|
74
83
|
end
|
75
84
|
end
|
76
85
|
|
77
86
|
def sync_app(app, path)
|
78
87
|
upload_app(app, path)
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
if input.given?(:memory)
|
83
|
-
mem = megabytes(input[:memory])
|
84
|
-
|
85
|
-
if mem != app.memory
|
86
|
-
diff[:memory] = [app.memory, mem]
|
87
|
-
app.memory = mem
|
88
|
-
end
|
89
|
-
end
|
90
|
-
|
91
|
-
if input.given?(:instances)
|
92
|
-
instances = input[:instances]
|
93
|
-
|
94
|
-
if instances != app.total_instances
|
95
|
-
diff[:instances] = [app.total_instances, instances]
|
96
|
-
app.total_instances = instances
|
97
|
-
end
|
98
|
-
end
|
99
|
-
|
100
|
-
if input.given?(:framework)
|
101
|
-
all_frameworks = client.frameworks
|
102
|
-
|
103
|
-
framework = input[:framework, all_frameworks, all_frameworks]
|
104
|
-
|
105
|
-
if framework != app.framework
|
106
|
-
diff[:framework] = [app.framework.name, framework.name]
|
107
|
-
app.framework = framework
|
108
|
-
end
|
109
|
-
end
|
110
|
-
|
111
|
-
if input.given?(:runtime)
|
112
|
-
all_runtimes = client.runtimes
|
113
|
-
|
114
|
-
runtime = input[:runtime, all_runtimes, all_runtimes]
|
115
|
-
|
116
|
-
if runtime != app.runtime
|
117
|
-
diff[:runtime] = [app.runtime.name, runtime.name]
|
118
|
-
app.runtime = runtime
|
119
|
-
end
|
120
|
-
end
|
121
|
-
|
122
|
-
if input.given?(:command) && input[:command] != app.command
|
123
|
-
command = input[:command]
|
124
|
-
|
125
|
-
if command != app.command
|
126
|
-
diff[:command] = [app.command, command]
|
127
|
-
app.command = command
|
128
|
-
end
|
129
|
-
end
|
130
|
-
|
131
|
-
if input.given?(:plan) && v2?
|
132
|
-
production = !!(input[:plan] =~ /^p/i)
|
133
|
-
|
134
|
-
if production != app.production
|
135
|
-
diff[:production] = [bool(app.production), bool(production)]
|
136
|
-
app.production = production
|
137
|
-
end
|
138
|
-
end
|
139
|
-
|
140
|
-
unless diff.empty?
|
141
|
-
line "Changes:"
|
142
|
-
|
143
|
-
indented do
|
144
|
-
diff.each do |name, change|
|
145
|
-
old, new = change
|
146
|
-
line "#{c(name, :name)}: #{old} #{c("->", :dim)} #{new}"
|
147
|
-
end
|
148
|
-
end
|
149
|
-
|
150
|
-
with_progress("Updating #{c(app.name, :name)}") do
|
151
|
-
app.update!
|
152
|
-
end
|
153
|
-
end
|
154
|
-
|
155
|
-
if input[:restart] && app.started?
|
156
|
-
invoke :restart, :app => app
|
157
|
-
end
|
88
|
+
apply_changes(app)
|
89
|
+
display_changes(app)
|
90
|
+
commit_changes(app)
|
158
91
|
end
|
159
92
|
|
160
|
-
def
|
161
|
-
|
162
|
-
app
|
163
|
-
app
|
164
|
-
app
|
165
|
-
app
|
166
|
-
|
167
|
-
detector = VMC::Detector.new(client, path)
|
168
|
-
all_frameworks = detector.all_frameworks
|
169
|
-
all_runtimes = detector.all_runtimes
|
170
|
-
|
171
|
-
if detected_framework = detector.detect_framework
|
172
|
-
framework = input[
|
173
|
-
:framework,
|
174
|
-
all_frameworks,
|
175
|
-
[detected_framework],
|
176
|
-
detected_framework,
|
177
|
-
:other
|
178
|
-
]
|
179
|
-
else
|
180
|
-
framework = input[:framework, all_frameworks, all_frameworks]
|
181
|
-
end
|
182
|
-
|
183
|
-
|
184
|
-
if framework.name == "standalone"
|
185
|
-
detected_runtimes = detector.detect_runtimes
|
186
|
-
else
|
187
|
-
detected_runtimes = detector.runtimes(framework)
|
188
|
-
end
|
189
|
-
|
190
|
-
if detected_runtimes.size == 1
|
191
|
-
default_runtime = detected_runtimes.first
|
192
|
-
end
|
193
|
-
|
194
|
-
if detected_runtimes.empty?
|
195
|
-
runtime = input[:runtime, all_runtimes, all_runtimes]
|
196
|
-
else
|
197
|
-
runtime = input[
|
198
|
-
:runtime,
|
199
|
-
all_runtimes,
|
200
|
-
detected_runtimes,
|
201
|
-
default_runtime,
|
202
|
-
:other
|
203
|
-
]
|
204
|
-
end
|
205
|
-
|
206
|
-
|
207
|
-
fail "Invalid framework '#{input[:framework]}'" unless framework
|
208
|
-
fail "Invalid runtime '#{input[:runtime]}'" unless runtime
|
209
|
-
|
210
|
-
app.framework = framework
|
211
|
-
app.runtime = runtime
|
212
|
-
|
213
|
-
app.command = input[:command] if framework.name == "standalone"
|
214
|
-
|
215
|
-
default_memory = detector.suggested_memory(framework) || 64
|
216
|
-
app.memory = megabytes(input[:memory, human_mb(default_memory)])
|
217
|
-
|
218
|
-
app = filter(:create_app, app)
|
219
|
-
|
220
|
-
with_progress("Creating #{c(app.name, :name)}") do
|
221
|
-
app.create!
|
222
|
-
end
|
223
|
-
|
224
|
-
line unless quiet?
|
225
|
-
|
226
|
-
url = input[:url, name]
|
227
|
-
|
228
|
-
mapped_url = false
|
229
|
-
until !url || mapped_url
|
230
|
-
begin
|
231
|
-
invoke :map, :app => app, :url => url
|
232
|
-
mapped_url = true
|
233
|
-
rescue CFoundry::RouteHostTaken, CFoundry::UriAlreadyTaken => e
|
234
|
-
line c(e.description, :bad)
|
235
|
-
line
|
236
|
-
|
237
|
-
input.forget(:url)
|
238
|
-
url = input[:url, name]
|
239
|
-
|
240
|
-
# version bumps on v1 even though mapping fails
|
241
|
-
app.invalidate! unless v2?
|
242
|
-
end
|
243
|
-
end
|
244
|
-
|
245
|
-
bindings = []
|
246
|
-
|
247
|
-
if input[:create_services] && !force?
|
248
|
-
while true
|
249
|
-
invoke :create_service, { :app => app }, :plan => :interact
|
250
|
-
break unless ask "Create another service?", :default => false
|
251
|
-
end
|
252
|
-
end
|
253
|
-
|
254
|
-
if input[:bind_services] && !force?
|
255
|
-
instances = client.service_instances
|
256
|
-
|
257
|
-
while true
|
258
|
-
invoke :bind_service, :app => app
|
259
|
-
|
260
|
-
break if (instances - app.services).empty?
|
261
|
-
|
262
|
-
break unless ask("Bind another service?", :default => false)
|
263
|
-
end
|
264
|
-
end
|
265
|
-
|
93
|
+
def setup_new_app(path)
|
94
|
+
self.path = path
|
95
|
+
app = create_app(get_inputs)
|
96
|
+
map_url(app)
|
97
|
+
create_services(app)
|
98
|
+
bind_services(app)
|
266
99
|
app = filter(:push_app, app)
|
267
|
-
|
268
|
-
|
269
|
-
upload_app(app, path)
|
270
|
-
rescue
|
271
|
-
err "Upload failed. Try again with 'vmc push'."
|
272
|
-
raise
|
273
|
-
end
|
274
|
-
|
275
|
-
invoke :start, :app => app if input[:start]
|
100
|
+
upload_app(app, path)
|
101
|
+
start_app(app)
|
276
102
|
end
|
277
103
|
|
278
104
|
private
|
279
105
|
|
280
|
-
def upload_app(app, path)
|
281
|
-
with_progress("Uploading #{c(app.name, :name)}") do
|
282
|
-
app.upload(path)
|
283
|
-
end
|
284
|
-
end
|
285
|
-
|
286
|
-
def bool(b)
|
287
|
-
if b
|
288
|
-
c("true", :yes)
|
289
|
-
else
|
290
|
-
c("false", :no)
|
291
|
-
end
|
292
|
-
end
|
293
|
-
|
294
106
|
def url_choices(name)
|
295
107
|
if v2?
|
296
108
|
client.current_space.domains.sort_by(&:name).collect do |d|
|
@@ -298,12 +110,17 @@ module VMC::App
|
|
298
110
|
"#{name}.#{d.name}"
|
299
111
|
end
|
300
112
|
else
|
301
|
-
|
113
|
+
%W(#{name}.#{target_base})
|
302
114
|
end
|
303
115
|
end
|
304
116
|
|
305
|
-
def
|
306
|
-
|
117
|
+
def upload_app(app, path)
|
118
|
+
with_progress("Uploading #{c(app.name, :name)}") do
|
119
|
+
app.upload(path)
|
120
|
+
end
|
121
|
+
rescue
|
122
|
+
err "Upload failed. Try again with 'vmc push'."
|
123
|
+
raise
|
307
124
|
end
|
308
125
|
|
309
126
|
def ask_with_other(message, all, choices, default, other)
|
@@ -0,0 +1,125 @@
|
|
1
|
+
module VMC::App
|
2
|
+
module Create
|
3
|
+
attr_accessor :input
|
4
|
+
attr_writer :path
|
5
|
+
|
6
|
+
def get_inputs
|
7
|
+
inputs = {}
|
8
|
+
inputs[:name] = input[:name]
|
9
|
+
inputs[:total_instances] = input[:instances]
|
10
|
+
inputs[:space] = client.current_space if client.current_space
|
11
|
+
inputs[:production] = !!(input[:plan] =~ /^p/i) if v2?
|
12
|
+
inputs[:framework] = framework = determine_framework
|
13
|
+
inputs[:command] = input[:command] if framework.name == "standalone"
|
14
|
+
inputs[:runtime] = determine_runtime(framework)
|
15
|
+
|
16
|
+
human_mb = human_mb(detector.suggested_memory(framework) || 64)
|
17
|
+
inputs[:memory] = megabytes(input[:memory, human_mb])
|
18
|
+
|
19
|
+
inputs
|
20
|
+
end
|
21
|
+
|
22
|
+
def determine_framework
|
23
|
+
return input[:framework] if input.given?(:framework)
|
24
|
+
|
25
|
+
if (detected_framework = detector.detect_framework)
|
26
|
+
input[:framework, [detected_framework], detected_framework, :other]
|
27
|
+
else
|
28
|
+
input[:framework, detector.all_frameworks, nil, nil]
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def determine_runtime(framework)
|
33
|
+
return input[:runtime] if input.given?(:runtime)
|
34
|
+
|
35
|
+
detected_runtimes =
|
36
|
+
if framework.name == "standalone"
|
37
|
+
detector.detect_runtimes
|
38
|
+
else
|
39
|
+
detector.runtimes(framework)
|
40
|
+
end
|
41
|
+
|
42
|
+
default_runtime = detected_runtimes.size == 1 ? detected_runtimes.first : nil
|
43
|
+
|
44
|
+
if detected_runtimes.empty?
|
45
|
+
input[:runtime, detector.all_runtimes, nil, nil]
|
46
|
+
else
|
47
|
+
input[:runtime, detected_runtimes, default_runtime, :other]
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def create_app(inputs)
|
52
|
+
app = client.app
|
53
|
+
|
54
|
+
inputs.each { |key, value| app.send(:"#{key}=", value) }
|
55
|
+
|
56
|
+
app = filter(:create_app, app)
|
57
|
+
|
58
|
+
with_progress("Creating #{c(app.name, :name)}") do
|
59
|
+
app.create!
|
60
|
+
end
|
61
|
+
|
62
|
+
app
|
63
|
+
end
|
64
|
+
|
65
|
+
def map_url(app)
|
66
|
+
line unless quiet?
|
67
|
+
|
68
|
+
url = input[:url, app.name]
|
69
|
+
|
70
|
+
mapped_url = false
|
71
|
+
until !url || mapped_url
|
72
|
+
begin
|
73
|
+
invoke :map, :app => app, :url => url
|
74
|
+
mapped_url = true
|
75
|
+
rescue CFoundry::RouteHostTaken, CFoundry::UriAlreadyTaken => e
|
76
|
+
line c(e.description, :bad)
|
77
|
+
line
|
78
|
+
|
79
|
+
input.forget(:url)
|
80
|
+
url = input[:url, app.name]
|
81
|
+
|
82
|
+
# version bumps on v1 even though mapping fails
|
83
|
+
app.invalidate! unless v2?
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
def create_services(app)
|
89
|
+
return unless input[:create_services]
|
90
|
+
|
91
|
+
while true
|
92
|
+
invoke :create_service, { :app => app }, :plan => :interact
|
93
|
+
break unless ask("Create another service?", :default => false)
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
def bind_services(app)
|
98
|
+
return unless input[:bind_services]
|
99
|
+
|
100
|
+
while true
|
101
|
+
invoke :bind_service, :app => app
|
102
|
+
break if (all_instances - app.services).empty?
|
103
|
+
break unless ask("Bind another service?", :default => false)
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
def start_app(app)
|
108
|
+
invoke :start, :app => app if input[:start]
|
109
|
+
end
|
110
|
+
|
111
|
+
private
|
112
|
+
|
113
|
+
def all_instances
|
114
|
+
@all_instances ||= client.service_instances
|
115
|
+
end
|
116
|
+
|
117
|
+
def detector
|
118
|
+
@detector ||= VMC::Detector.new(client, @path)
|
119
|
+
end
|
120
|
+
|
121
|
+
def target_base
|
122
|
+
client.target.sub(/^https?:\/\/([^\.]+\.)?(.+)\/?/, '\2')
|
123
|
+
end
|
124
|
+
end
|
125
|
+
end
|