as 0.3.18.11
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of as might be problematic. Click here for more details.
- data/LICENSE +24 -0
- data/README.md +105 -0
- data/Rakefile +101 -0
- data/bin/as +6 -0
- data/caldecott_helper/Gemfile +10 -0
- data/caldecott_helper/Gemfile.lock +48 -0
- data/caldecott_helper/server.rb +43 -0
- data/config/clients.yml +17 -0
- data/config/micro/offline.conf +2 -0
- data/config/micro/paths.yml +22 -0
- data/config/micro/refresh_ip.rb +20 -0
- data/lib/cli/commands/admin.rb +80 -0
- data/lib/cli/commands/apps.rb +1208 -0
- data/lib/cli/commands/base.rb +233 -0
- data/lib/cli/commands/manifest.rb +56 -0
- data/lib/cli/commands/micro.rb +115 -0
- data/lib/cli/commands/misc.rb +140 -0
- data/lib/cli/commands/services.rb +217 -0
- data/lib/cli/commands/user.rb +65 -0
- data/lib/cli/config.rb +170 -0
- data/lib/cli/console_helper.rb +163 -0
- data/lib/cli/core_ext.rb +122 -0
- data/lib/cli/errors.rb +19 -0
- data/lib/cli/file_helper.rb +123 -0
- data/lib/cli/frameworks.rb +265 -0
- data/lib/cli/manifest_helper.rb +316 -0
- data/lib/cli/runner.rb +568 -0
- data/lib/cli/services_helper.rb +104 -0
- data/lib/cli/tunnel_helper.rb +336 -0
- data/lib/cli/usage.rb +125 -0
- data/lib/cli/version.rb +7 -0
- data/lib/cli/zip_util.rb +77 -0
- data/lib/cli.rb +48 -0
- data/lib/vmc/client.rb +558 -0
- data/lib/vmc/const.rb +27 -0
- data/lib/vmc/micro/switcher/base.rb +97 -0
- data/lib/vmc/micro/switcher/darwin.rb +19 -0
- data/lib/vmc/micro/switcher/dummy.rb +15 -0
- data/lib/vmc/micro/switcher/linux.rb +16 -0
- data/lib/vmc/micro/switcher/windows.rb +31 -0
- data/lib/vmc/micro/vmrun.rb +158 -0
- data/lib/vmc/micro.rb +56 -0
- data/lib/vmc.rb +3 -0
- metadata +270 -0
@@ -0,0 +1,316 @@
|
|
1
|
+
require "set"
|
2
|
+
|
3
|
+
module VMC::Cli::ManifestHelper
|
4
|
+
include VMC::Cli::ServicesHelper
|
5
|
+
|
6
|
+
DEFAULTS = {
|
7
|
+
"url" => "${name}.${target-base}",
|
8
|
+
"mem" => "128M",
|
9
|
+
"instances" => 1
|
10
|
+
}
|
11
|
+
|
12
|
+
MANIFEST = "manifest.yml"
|
13
|
+
|
14
|
+
YES_SET = Set.new(["y", "Y", "yes", "YES"])
|
15
|
+
|
16
|
+
# take a block and call it once for each app to push/update.
|
17
|
+
# with @application and @app_info set appropriately
|
18
|
+
def each_app(panic=true)
|
19
|
+
if @manifest and all_apps = @manifest["applications"]
|
20
|
+
where = File.expand_path(@path)
|
21
|
+
single = false
|
22
|
+
|
23
|
+
all_apps.each do |path, info|
|
24
|
+
app = File.expand_path("../" + path, manifest_file)
|
25
|
+
if where.start_with?(app)
|
26
|
+
@application = app
|
27
|
+
@app_info = info
|
28
|
+
yield info["name"]
|
29
|
+
single = true
|
30
|
+
break
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
unless single
|
35
|
+
if where == File.expand_path("../", manifest_file)
|
36
|
+
ordered_by_deps(all_apps).each do |path, info|
|
37
|
+
app = File.expand_path("../" + path, manifest_file)
|
38
|
+
@application = app
|
39
|
+
@app_info = info
|
40
|
+
yield info["name"]
|
41
|
+
end
|
42
|
+
else
|
43
|
+
err "Path '#{@path}' is not known to manifest '#{manifest_file}'."
|
44
|
+
end
|
45
|
+
end
|
46
|
+
else
|
47
|
+
@application = @path
|
48
|
+
@app_info = @manifest
|
49
|
+
if @app_info
|
50
|
+
yield @app_info["name"]
|
51
|
+
elsif panic
|
52
|
+
err "No applications."
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
nil
|
57
|
+
ensure
|
58
|
+
@application = nil
|
59
|
+
@app_info = nil
|
60
|
+
end
|
61
|
+
|
62
|
+
def interact(many=false)
|
63
|
+
@manifest ||= {}
|
64
|
+
configure_app(many)
|
65
|
+
end
|
66
|
+
|
67
|
+
def target_manifest
|
68
|
+
@options[:manifest] || MANIFEST
|
69
|
+
end
|
70
|
+
|
71
|
+
def save_manifest(save_to = nil)
|
72
|
+
save_to ||= target_manifest
|
73
|
+
|
74
|
+
File.open(save_to, "w") do |f|
|
75
|
+
f.write @manifest.to_yaml
|
76
|
+
end
|
77
|
+
|
78
|
+
say "Manifest written to #{save_to}."
|
79
|
+
end
|
80
|
+
|
81
|
+
def configure_app(many=false)
|
82
|
+
name = manifest("name") ||
|
83
|
+
set(ask("Application Name", :default => manifest("name")), "name")
|
84
|
+
|
85
|
+
if manifest "framework"
|
86
|
+
framework = VMC::Cli::Framework.lookup_by_framework manifest("framework","name")
|
87
|
+
else
|
88
|
+
framework = detect_framework
|
89
|
+
set framework.name, "framework", "name"
|
90
|
+
set(
|
91
|
+
{ "mem" => framework.mem,
|
92
|
+
"description" => framework.description,
|
93
|
+
"exec" => framework.exec
|
94
|
+
},
|
95
|
+
"framework",
|
96
|
+
"info"
|
97
|
+
)
|
98
|
+
end
|
99
|
+
|
100
|
+
default_runtime = manifest "runtime"
|
101
|
+
if not default_runtime
|
102
|
+
default_runtime = framework.default_runtime(@application)
|
103
|
+
set(detect_runtime(default_runtime), "runtime") if framework.prompt_for_runtime?
|
104
|
+
end
|
105
|
+
default_command = manifest "command"
|
106
|
+
set ask("Start Command", :default => default_command), "command" if framework.require_start_command?
|
107
|
+
|
108
|
+
if client.infra_supported?
|
109
|
+
infra = @options[:infra] || manifest("infra") ||
|
110
|
+
client.infra_name_for_description(
|
111
|
+
ask("Select Infrastructure",:indexed => true, :choices => client.infra_descriptions))
|
112
|
+
set infra.dup, "infra"
|
113
|
+
client.infra = infra
|
114
|
+
end
|
115
|
+
|
116
|
+
url_template = manifest("url") || DEFAULTS["url"]
|
117
|
+
url_resolved = url_template.dup
|
118
|
+
resolve_lexically(url_resolved)
|
119
|
+
|
120
|
+
if !framework.require_url?
|
121
|
+
url_resolved = "None"
|
122
|
+
end
|
123
|
+
url = ask("Application Deployed URL", :default => url_resolved)
|
124
|
+
|
125
|
+
if url == url_resolved && url != "None"
|
126
|
+
url = url_template
|
127
|
+
end
|
128
|
+
|
129
|
+
# common error case is for prompted users to answer y or Y or yes or
|
130
|
+
# YES to this ask() resulting in an unintended URL of y. Special
|
131
|
+
# case this common error
|
132
|
+
url = url_resolved if YES_SET.member? url
|
133
|
+
|
134
|
+
if(url == "None")
|
135
|
+
url = nil
|
136
|
+
end
|
137
|
+
|
138
|
+
set url, "url"
|
139
|
+
|
140
|
+
default_mem = manifest("mem")
|
141
|
+
default_mem = framework.memory(manifest("runtime")) if not default_mem
|
142
|
+
set ask(
|
143
|
+
"Memory reservation",
|
144
|
+
:default =>
|
145
|
+
default_mem ||
|
146
|
+
DEFAULTS["mem"],
|
147
|
+
:choices => ["128M", "256M", "512M", "1G", "2G"]
|
148
|
+
), "mem"
|
149
|
+
|
150
|
+
set ask(
|
151
|
+
"How many instances?",
|
152
|
+
:default => manifest("instances") || DEFAULTS["instances"]
|
153
|
+
), "instances"
|
154
|
+
|
155
|
+
unless manifest "services"
|
156
|
+
user_services = services_for_infra(manifest("infra"))
|
157
|
+
user_services.sort! {|a, b| a[:name] <=> b[:name] }
|
158
|
+
|
159
|
+
unless user_services.empty?
|
160
|
+
if ask "Bind existing services to '#{name}'?", :default => false
|
161
|
+
bind_services(user_services)
|
162
|
+
end
|
163
|
+
end
|
164
|
+
|
165
|
+
services = client.services_info
|
166
|
+
unless services.empty?
|
167
|
+
if ask "Create services to bind to '#{name}'?", :default => false
|
168
|
+
create_services(services.values.collect(&:keys).flatten)
|
169
|
+
end
|
170
|
+
end
|
171
|
+
end
|
172
|
+
|
173
|
+
if many and ask("Configure for another application?", :default => false)
|
174
|
+
@application = ask "Application path?"
|
175
|
+
configure_app
|
176
|
+
end
|
177
|
+
end
|
178
|
+
|
179
|
+
def set(what, *where)
|
180
|
+
where.unshift "applications", @application
|
181
|
+
|
182
|
+
which = @manifest
|
183
|
+
where.each_with_index do |k, i|
|
184
|
+
if i + 1 == where.size
|
185
|
+
which[k] = what
|
186
|
+
else
|
187
|
+
which = (which[k] ||= {})
|
188
|
+
end
|
189
|
+
end
|
190
|
+
|
191
|
+
what
|
192
|
+
end
|
193
|
+
|
194
|
+
# Detect the appropriate framework.
|
195
|
+
def detect_framework(prompt_ok = true)
|
196
|
+
framework = VMC::Cli::Framework.detect(@application, frameworks_info)
|
197
|
+
framework_correct = ask("Detected a #{framework}, is this correct?", :default => true) if prompt_ok && framework
|
198
|
+
if prompt_ok && (framework.nil? || !framework_correct)
|
199
|
+
display "#{"[WARNING]".yellow} Can't determine the Application Type." unless framework
|
200
|
+
framework = nil if !framework_correct
|
201
|
+
framework = VMC::Cli::Framework.lookup(
|
202
|
+
ask(
|
203
|
+
"Select Application Type",
|
204
|
+
:indexed => true,
|
205
|
+
:default => framework,
|
206
|
+
:choices => VMC::Cli::Framework.known_frameworks(frameworks_info)
|
207
|
+
)
|
208
|
+
)
|
209
|
+
display "Selected #{framework}"
|
210
|
+
end
|
211
|
+
|
212
|
+
framework
|
213
|
+
end
|
214
|
+
|
215
|
+
# Detect the appropriate runtime.
|
216
|
+
def detect_runtime(default, prompt_ok=true)
|
217
|
+
runtime = nil
|
218
|
+
runtime_keys=[]
|
219
|
+
runtimes_info.keys.each {|runtime_key| runtime_keys << runtime_key.dup }
|
220
|
+
runtime_keys.sort!
|
221
|
+
if prompt_ok
|
222
|
+
runtime = ask(
|
223
|
+
"Select Runtime",
|
224
|
+
:indexed => true,
|
225
|
+
:default => default,
|
226
|
+
:choices => runtime_keys
|
227
|
+
)
|
228
|
+
display "Selected #{runtime}"
|
229
|
+
end
|
230
|
+
runtime
|
231
|
+
end
|
232
|
+
|
233
|
+
def bind_services(user_services, chosen = 0)
|
234
|
+
svcname = ask(
|
235
|
+
"Which one?",
|
236
|
+
:indexed => true,
|
237
|
+
:choices => user_services.collect { |p| p[:name] })
|
238
|
+
|
239
|
+
svc = user_services.find { |p| p[:name] == svcname }
|
240
|
+
|
241
|
+
set svc[:vendor], "services", svcname, "type"
|
242
|
+
|
243
|
+
if chosen + 1 < user_services.size && ask("Bind another?", :default => false)
|
244
|
+
bind_services(user_services, chosen + 1)
|
245
|
+
end
|
246
|
+
end
|
247
|
+
|
248
|
+
def create_services(services)
|
249
|
+
svcs = services.collect(&:to_s).sort!
|
250
|
+
|
251
|
+
configure_service(
|
252
|
+
ask(
|
253
|
+
"What kind of service?",
|
254
|
+
:indexed => true,
|
255
|
+
:choices => svcs
|
256
|
+
)
|
257
|
+
)
|
258
|
+
|
259
|
+
if ask "Create another?", :default => false
|
260
|
+
create_services(services)
|
261
|
+
end
|
262
|
+
end
|
263
|
+
|
264
|
+
def configure_service(vendor)
|
265
|
+
default_name = random_service_name(vendor)
|
266
|
+
name = ask "Specify the name of the service", :default => default_name
|
267
|
+
|
268
|
+
set vendor, "services", name, "type"
|
269
|
+
end
|
270
|
+
|
271
|
+
private
|
272
|
+
def services_for_infra(infra)
|
273
|
+
if client.infra_supported?
|
274
|
+
client.services.select { |s| s[:infra] && s[:infra][:provider] == manifest("infra") }
|
275
|
+
else
|
276
|
+
client.services
|
277
|
+
end
|
278
|
+
end
|
279
|
+
|
280
|
+
def ordered_by_deps(apps, abspaths = nil, processed = Set[])
|
281
|
+
unless abspaths
|
282
|
+
abspaths = {}
|
283
|
+
apps.each do |p, i|
|
284
|
+
ep = File.expand_path("../" + p, manifest_file)
|
285
|
+
abspaths[ep] = i
|
286
|
+
end
|
287
|
+
end
|
288
|
+
|
289
|
+
ordered = []
|
290
|
+
apps.each do |path, info|
|
291
|
+
epath = File.expand_path("../" + path, manifest_file)
|
292
|
+
|
293
|
+
if deps = info["depends-on"]
|
294
|
+
dep_apps = {}
|
295
|
+
deps.each do |dep|
|
296
|
+
edep = File.expand_path("../" + dep, manifest_file)
|
297
|
+
|
298
|
+
err "Circular dependency detected." if processed.include? edep
|
299
|
+
|
300
|
+
dep_apps[dep] = abspaths[edep]
|
301
|
+
end
|
302
|
+
|
303
|
+
processed.add(epath)
|
304
|
+
|
305
|
+
ordered += ordered_by_deps(dep_apps, abspaths, processed)
|
306
|
+
ordered << [path, info]
|
307
|
+
elsif not processed.include? epath
|
308
|
+
ordered << [path, info]
|
309
|
+
processed.add(epath)
|
310
|
+
end
|
311
|
+
end
|
312
|
+
|
313
|
+
ordered
|
314
|
+
end
|
315
|
+
|
316
|
+
end
|