vmc 0.4.2 → 0.4.3
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/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
|