manifests-vmc-plugin 0.2.4 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/manifests-vmc-plugin/plugin.rb +63 -124
- data/lib/manifests-vmc-plugin/version.rb +1 -1
- data/lib/manifests-vmc-plugin.rb +90 -60
- metadata +5 -5
@@ -1,161 +1,100 @@
|
|
1
1
|
require "vmc/plugin"
|
2
2
|
require "manifests-vmc-plugin"
|
3
3
|
|
4
|
-
VMC.Plugin do
|
5
|
-
class_option :manifest,
|
6
|
-
:aliases => "-m", :desc => "Manifest file"
|
7
4
|
|
8
|
-
|
9
|
-
:aliases => "-p", :desc => "Application path"
|
10
|
-
end
|
11
|
-
|
12
|
-
VMC.Plugin(VMC::App) do
|
5
|
+
class Manifests < VMC::CLI
|
13
6
|
include VMCManifests
|
14
7
|
|
15
|
-
|
16
|
-
|
17
|
-
[:start, :instances, :logs, :file, :files, :health, :stats].each do |wrap|
|
18
|
-
around(wrap) do |cmd, args|
|
19
|
-
if args.empty? && !passed_value(:name)
|
20
|
-
each_app do |a|
|
21
|
-
cmd.call(:name => a["name"])
|
22
|
-
puts "" unless simple_output?
|
23
|
-
end || err("No applications to act on.")
|
24
|
-
else
|
25
|
-
cmd.call
|
26
|
-
end
|
27
|
-
end
|
28
|
-
end
|
8
|
+
option :manifest, :aliases => "-m", :value => :file,
|
9
|
+
:desc => "Path to manifest file to use"
|
29
10
|
|
30
|
-
# same as above but in reverse dependency-order
|
31
|
-
around(:stop) do |cmd, args|
|
32
|
-
if args.empty? && !passed_value(:name)
|
33
|
-
reversed = []
|
34
|
-
each_app do |a|
|
35
|
-
reversed.unshift a["name"]
|
36
|
-
end || err("No applications to act on.")
|
37
11
|
|
38
|
-
|
39
|
-
|
40
|
-
puts "" unless simple_output?
|
41
|
-
end
|
42
|
-
else
|
43
|
-
cmd.call
|
44
|
-
end
|
12
|
+
def no_apps
|
13
|
+
err "No applications or manifest to operate on."
|
45
14
|
end
|
46
15
|
|
47
|
-
around(:delete) do |cmd, args|
|
48
|
-
if args.empty? && !options[:all] && !passed_value(:name)
|
49
|
-
reversed = []
|
50
|
-
has_manifest =
|
51
|
-
each_app do |a|
|
52
|
-
reversed.unshift a["name"]
|
53
|
-
end
|
54
16
|
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
17
|
+
# basic commands that, when given no name, act on the
|
18
|
+
# app(s) described by the manifest, in dependency-order
|
19
|
+
[ :start, :instances, :logs, :file, :files, :env,
|
20
|
+
:health, :stats, :scale
|
21
|
+
].each do |wrap|
|
22
|
+
change_argument(wrap, :name, :optional)
|
23
|
+
|
24
|
+
around(wrap) do |cmd, input|
|
25
|
+
use_manifest =
|
26
|
+
specific_apps_or_all(input) do |app|
|
27
|
+
cmd.call(input.merge(:name => app[:name]))
|
28
|
+
puts "" unless quiet?
|
59
29
|
end
|
60
|
-
|
61
|
-
|
30
|
+
|
31
|
+
# array of unhandled names
|
32
|
+
if use_manifest === Array
|
33
|
+
cmd.call(input.merge(:names => use_manifest))
|
34
|
+
|
35
|
+
# no manifest or no apps described by it
|
36
|
+
elsif !use_manifest
|
37
|
+
no_apps
|
62
38
|
end
|
63
|
-
else
|
64
|
-
cmd.call
|
65
39
|
end
|
66
40
|
end
|
67
41
|
|
68
|
-
|
69
|
-
#
|
70
|
-
|
71
|
-
|
42
|
+
|
43
|
+
# same as above but in reverse dependency-order
|
44
|
+
[:stop, :delete].each do |wrap|
|
45
|
+
around(wrap) do |cmd, input|
|
46
|
+
next cmd.call if input[:all]
|
47
|
+
|
72
48
|
reversed = []
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
forwards << a["name"]
|
77
|
-
end || err("No applications to act on.")
|
78
|
-
|
79
|
-
reversed.each do |name|
|
80
|
-
with_inputs(:name => name) do
|
81
|
-
stop
|
49
|
+
use_manifest =
|
50
|
+
specific_apps_or_all(input) do |app|
|
51
|
+
reversed.unshift app[:name]
|
82
52
|
end
|
83
|
-
end
|
84
53
|
|
85
|
-
|
54
|
+
# array of unhandled names
|
55
|
+
if use_manifest === Array
|
56
|
+
cmd.call(input.merge(:names => use_manifest))
|
86
57
|
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
end
|
58
|
+
# no manifest or no apps described by it
|
59
|
+
elsif !use_manifest
|
60
|
+
next no_apps
|
91
61
|
end
|
92
|
-
|
93
|
-
cmd.call
|
62
|
+
|
63
|
+
cmd.call(input.merge(:names => reversed))
|
94
64
|
end
|
95
65
|
end
|
96
66
|
|
67
|
+
|
97
68
|
# push and sync meta changes in the manifest
|
98
69
|
# also sets env data on creation if present in manifest
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
all_pushed =
|
111
|
-
each_app do |info|
|
112
|
-
next if !use_name && name && info["name"] != name
|
113
|
-
|
114
|
-
app_name = use_name ? name : info["name"]
|
115
|
-
|
116
|
-
app = client.app(app_name)
|
117
|
-
|
118
|
-
sync_changes(info)
|
119
|
-
|
120
|
-
with_filters(:push_app => proc { |a| setup_app(a, info); a }) do
|
70
|
+
change_argument(:push, :name, :optional)
|
71
|
+
around(:push) do |push, input|
|
72
|
+
use_manifest =
|
73
|
+
specific_apps_or_all(input, true) do |app|
|
74
|
+
sync_changes(app)
|
75
|
+
|
76
|
+
with_filters(
|
77
|
+
:push => {
|
78
|
+
:push_app =>
|
79
|
+
proc { |a| setup_app(a, app); a }
|
80
|
+
}) do
|
121
81
|
push.call(
|
122
|
-
|
123
|
-
|
124
|
-
|
82
|
+
input.merge(app).merge(
|
83
|
+
:bind_services => false,
|
84
|
+
:create_services => false))
|
125
85
|
end
|
126
|
-
|
127
|
-
puts "" unless simple_output?
|
128
86
|
end
|
129
87
|
|
130
|
-
unless
|
88
|
+
unless use_manifest
|
131
89
|
bound = []
|
132
90
|
|
133
|
-
with_filters(
|
91
|
+
with_filters(
|
92
|
+
:push => {
|
93
|
+
:push_app =>
|
94
|
+
proc { |a| ask_to_save(input, a); a }
|
95
|
+
}) do
|
134
96
|
push.call
|
135
97
|
end
|
136
98
|
end
|
137
99
|
end
|
138
|
-
|
139
|
-
# need to do this specially so it doesn't call it with the instance/memory
|
140
|
-
# flags set (via each_app), which would cause it to do nothing
|
141
|
-
around(:scale) do |cmd, args|
|
142
|
-
if args.empty? && !passed_value(:name)
|
143
|
-
apps = []
|
144
|
-
has_manifest =
|
145
|
-
each_app do |a|
|
146
|
-
apps << a["name"]
|
147
|
-
end
|
148
|
-
|
149
|
-
if has_manifest
|
150
|
-
apps.each do |name|
|
151
|
-
cmd.call(:name => name)
|
152
|
-
puts "" unless simple_output?
|
153
|
-
end
|
154
|
-
else
|
155
|
-
cmd.call
|
156
|
-
end
|
157
|
-
else
|
158
|
-
cmd.call
|
159
|
-
end
|
160
|
-
end
|
161
100
|
end
|
data/lib/manifests-vmc-plugin.rb
CHANGED
@@ -22,7 +22,7 @@ module VMCManifests
|
|
22
22
|
|
23
23
|
# find the manifest file to work with
|
24
24
|
def manifest_file
|
25
|
-
return
|
25
|
+
return option(:manifest) if option(:manifest)
|
26
26
|
return @manifest_file if @manifest_file
|
27
27
|
|
28
28
|
where = Dir.pwd
|
@@ -188,60 +188,58 @@ module VMCManifests
|
|
188
188
|
end
|
189
189
|
end
|
190
190
|
|
191
|
-
def app_info(find_path)
|
192
|
-
return unless manifest
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
191
|
+
def app_info(find_path, input = nil)
|
192
|
+
return unless manifest
|
193
|
+
|
194
|
+
mandir = File.dirname(manifest_file)
|
195
|
+
full_path = File.expand_path(find_path, mandir)
|
196
|
+
|
197
|
+
path, info =
|
198
|
+
if apps = manifest["applications"]
|
199
|
+
manifest["applications"].find do |path, info|
|
200
|
+
if info["framework"].is_a?(Hash)
|
201
|
+
info["framework"] = info["framework"]["name"]
|
202
|
+
end
|
203
|
+
|
204
|
+
app = File.expand_path(path, mandir)
|
205
|
+
File.expand_path(path, mandir) == full_path
|
206
|
+
end
|
207
|
+
elsif find_path == "."
|
208
|
+
[".", {}]
|
197
209
|
end
|
198
210
|
|
199
|
-
|
200
|
-
|
201
|
-
|
211
|
+
return unless info
|
212
|
+
|
213
|
+
data = { :path => full_path }
|
214
|
+
|
215
|
+
toplevel_attributes.merge(info).each do |k, v|
|
216
|
+
name = k.to_sym
|
217
|
+
|
218
|
+
if name == :mem
|
219
|
+
name = :memory
|
202
220
|
end
|
221
|
+
|
222
|
+
data[name] = input && input.given(name) || v
|
203
223
|
end
|
204
224
|
|
205
|
-
|
225
|
+
data
|
206
226
|
end
|
207
227
|
|
208
228
|
# call a block for each app in a manifest (in dependency order), setting
|
209
229
|
# inputs for each app
|
210
|
-
def each_app
|
211
|
-
given_path = passed_value(:path)
|
212
|
-
full_path = given_path && File.expand_path(given_path)
|
213
|
-
|
230
|
+
def each_app(input = nil, &blk)
|
214
231
|
if manifest and all_apps = manifest["applications"]
|
215
232
|
use_inputs = all_apps.size == 1
|
216
233
|
|
217
|
-
|
218
|
-
|
219
|
-
if info = app_info(full_path)
|
220
|
-
with_app(full_path, info, use_inputs) do
|
221
|
-
yield info
|
222
|
-
end
|
223
|
-
else
|
224
|
-
raise "Path #{given_path} is not described by the manifest."
|
225
|
-
end
|
226
|
-
else
|
227
|
-
# all apps in the manifest
|
228
|
-
ordered_by_deps(all_apps).each do |path|
|
229
|
-
app = File.expand_path(path, File.dirname(manifest_file))
|
230
|
-
info = app_info(app)
|
231
|
-
|
232
|
-
with_app(app, info, use_inputs) do
|
233
|
-
yield info
|
234
|
-
end
|
235
|
-
end
|
234
|
+
ordered_by_deps(all_apps).each do |path|
|
235
|
+
yield app_info(path, use_inputs && input)
|
236
236
|
end
|
237
237
|
|
238
238
|
true
|
239
|
-
|
239
|
+
|
240
240
|
# manually created or legacy single-app manifest
|
241
241
|
elsif single = toplevel_attributes
|
242
|
-
|
243
|
-
yield single
|
244
|
-
end
|
242
|
+
yield app_info(".", input)
|
245
243
|
|
246
244
|
true
|
247
245
|
|
@@ -250,24 +248,56 @@ module VMCManifests
|
|
250
248
|
end
|
251
249
|
end
|
252
250
|
|
253
|
-
|
251
|
+
# like each_app, but only acts on apps specified as paths instead of names
|
252
|
+
#
|
253
|
+
# returns the names that were not paths
|
254
|
+
def specific_apps_or_all(input = nil, use_name = true, &blk)
|
255
|
+
return false unless manifest && apps = manifest["applications"]
|
254
256
|
|
255
|
-
|
256
|
-
def with_app(path, info, use_inputs = false, &blk)
|
257
|
-
inputs = {:path => path}
|
258
|
-
info.each do |k, v|
|
259
|
-
input = k.to_sym
|
257
|
+
use_name = false if apps.size > 1
|
260
258
|
|
261
|
-
|
262
|
-
|
259
|
+
names_or_paths =
|
260
|
+
if input.given?(:names)
|
261
|
+
input[:names]
|
262
|
+
elsif input.given?(:name)
|
263
|
+
[input[:name]]
|
264
|
+
else
|
265
|
+
[]
|
263
266
|
end
|
264
267
|
|
265
|
-
|
268
|
+
return each_app(input, &blk) if names_or_paths.empty?
|
269
|
+
|
270
|
+
input = input.without(:name, :names)
|
271
|
+
|
272
|
+
paths = []
|
273
|
+
names = []
|
274
|
+
names_or_paths.each do |x|
|
275
|
+
path = File.expand_path(x)
|
276
|
+
|
277
|
+
if File.exists?(path)
|
278
|
+
paths << path
|
279
|
+
else
|
280
|
+
names << x
|
281
|
+
end
|
266
282
|
end
|
267
283
|
|
268
|
-
|
284
|
+
paths.each do |path|
|
285
|
+
blk.call app_info(path, input)
|
286
|
+
end
|
287
|
+
|
288
|
+
if use_name && names.size == 1
|
289
|
+
blk.call(
|
290
|
+
app_info(
|
291
|
+
manifest["applications"].keys.first,
|
292
|
+
input.merge(:name => names.first)))
|
293
|
+
end
|
294
|
+
|
295
|
+
names
|
269
296
|
end
|
270
297
|
|
298
|
+
|
299
|
+
private
|
300
|
+
|
271
301
|
# sort applications in dependency order
|
272
302
|
# e.g. if A depends on B, B will be listed before A
|
273
303
|
def ordered_by_deps(apps, abspaths = nil, processed = Set[])
|
@@ -313,18 +343,18 @@ module VMCManifests
|
|
313
343
|
# redeploys the app if necessary (after prompting the user), e.g. for
|
314
344
|
# runtime/framework change
|
315
345
|
def sync_changes(info)
|
316
|
-
app = client.app(info[
|
346
|
+
app = client.app(info[:name])
|
317
347
|
return unless app.exists?
|
318
348
|
|
319
349
|
diff = {}
|
320
350
|
need_restage = []
|
321
351
|
info.each do |k, v|
|
322
|
-
case k
|
352
|
+
case k.to_s
|
323
353
|
when /ur[li]s?/
|
324
354
|
old = app.urls
|
325
355
|
new = Array(v)
|
326
356
|
if old != new
|
327
|
-
diff[
|
357
|
+
diff[:urls] = [old.inspect, new.inspect]
|
328
358
|
app.urls = new
|
329
359
|
end
|
330
360
|
when "env"
|
@@ -351,7 +381,7 @@ module VMCManifests
|
|
351
381
|
new = megabytes(v)
|
352
382
|
|
353
383
|
if old != new
|
354
|
-
diff[
|
384
|
+
diff[:memory] = [human_size(old * 1024 * 1024, 0), v]
|
355
385
|
app.memory = new
|
356
386
|
end
|
357
387
|
end
|
@@ -359,7 +389,7 @@ module VMCManifests
|
|
359
389
|
|
360
390
|
return if diff.empty?
|
361
391
|
|
362
|
-
unless
|
392
|
+
unless quiet?
|
363
393
|
puts "Detected the following changes to #{c(app.name, :name)}:"
|
364
394
|
diff.each do |k, d|
|
365
395
|
old, new = d
|
@@ -375,7 +405,7 @@ module VMCManifests
|
|
375
405
|
app.update!
|
376
406
|
end
|
377
407
|
else
|
378
|
-
unless
|
408
|
+
unless quiet?
|
379
409
|
puts "The following changes require the app to be recreated:"
|
380
410
|
need_restage.each do |n|
|
381
411
|
puts " #{c(n, :error)}"
|
@@ -395,7 +425,7 @@ module VMCManifests
|
|
395
425
|
end
|
396
426
|
end
|
397
427
|
|
398
|
-
def ask_to_save(app)
|
428
|
+
def ask_to_save(input, app)
|
399
429
|
return if manifest_file
|
400
430
|
|
401
431
|
services = app.services.collect { |name| client.service(name) }
|
@@ -427,7 +457,7 @@ module VMCManifests
|
|
427
457
|
if ask("Save configuration?", :default => false)
|
428
458
|
File.open("manifest.yml", "w") do |io|
|
429
459
|
YAML.dump(
|
430
|
-
{"applications" => {(
|
460
|
+
{"applications" => {(input[:path] || ".") => meta}},
|
431
461
|
io)
|
432
462
|
end
|
433
463
|
|
@@ -436,13 +466,13 @@ module VMCManifests
|
|
436
466
|
end
|
437
467
|
|
438
468
|
def setup_app(app, info)
|
439
|
-
app.env = info[
|
469
|
+
app.env = info[:env]
|
440
470
|
|
441
|
-
return if !info[
|
471
|
+
return if !info[:services] || info[:services].empty?
|
442
472
|
|
443
473
|
services = client.system_services
|
444
474
|
|
445
|
-
info[
|
475
|
+
info[:services].each do |name, svc|
|
446
476
|
service = client.service(name)
|
447
477
|
|
448
478
|
unless service.exists?
|
@@ -460,6 +490,6 @@ module VMCManifests
|
|
460
490
|
end
|
461
491
|
end
|
462
492
|
|
463
|
-
app.services = info[
|
493
|
+
app.services = info[:services].keys
|
464
494
|
end
|
465
495
|
end
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: manifests-vmc-plugin
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 19
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 0
|
8
|
-
-
|
9
|
-
-
|
10
|
-
version: 0.
|
8
|
+
- 3
|
9
|
+
- 0
|
10
|
+
version: 0.3.0
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Alex Suraci
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2012-
|
18
|
+
date: 2012-07-03 00:00:00 Z
|
19
19
|
dependencies: []
|
20
20
|
|
21
21
|
description:
|