olympe 0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (44) hide show
  1. data/LICENSE +24 -0
  2. data/README.md +103 -0
  3. data/Rakefile +101 -0
  4. data/bin/olympe +6 -0
  5. data/caldecott_helper/Gemfile +10 -0
  6. data/caldecott_helper/Gemfile.lock +48 -0
  7. data/caldecott_helper/server.rb +43 -0
  8. data/config/clients.yml +17 -0
  9. data/config/micro/offline.conf +2 -0
  10. data/config/micro/paths.yml +22 -0
  11. data/config/micro/refresh_ip.rb +20 -0
  12. data/lib/cli/commands/admin.rb +80 -0
  13. data/lib/cli/commands/apps.rb +1208 -0
  14. data/lib/cli/commands/base.rb +233 -0
  15. data/lib/cli/commands/manifest.rb +56 -0
  16. data/lib/cli/commands/micro.rb +115 -0
  17. data/lib/cli/commands/misc.rb +140 -0
  18. data/lib/cli/commands/services.rb +217 -0
  19. data/lib/cli/commands/user.rb +65 -0
  20. data/lib/cli/config.rb +170 -0
  21. data/lib/cli/console_helper.rb +163 -0
  22. data/lib/cli/core_ext.rb +122 -0
  23. data/lib/cli/errors.rb +19 -0
  24. data/lib/cli/file_helper.rb +123 -0
  25. data/lib/cli/frameworks.rb +265 -0
  26. data/lib/cli/manifest_helper.rb +316 -0
  27. data/lib/cli/runner.rb +568 -0
  28. data/lib/cli/services_helper.rb +104 -0
  29. data/lib/cli/tunnel_helper.rb +336 -0
  30. data/lib/cli/usage.rb +125 -0
  31. data/lib/cli/version.rb +7 -0
  32. data/lib/cli/zip_util.rb +77 -0
  33. data/lib/cli.rb +48 -0
  34. data/lib/vmc/client.rb +558 -0
  35. data/lib/vmc/const.rb +27 -0
  36. data/lib/vmc/micro/switcher/base.rb +97 -0
  37. data/lib/vmc/micro/switcher/darwin.rb +19 -0
  38. data/lib/vmc/micro/switcher/dummy.rb +15 -0
  39. data/lib/vmc/micro/switcher/linux.rb +16 -0
  40. data/lib/vmc/micro/switcher/windows.rb +31 -0
  41. data/lib/vmc/micro/vmrun.rb +158 -0
  42. data/lib/vmc/micro.rb +56 -0
  43. data/lib/vmc.rb +3 -0
  44. metadata +279 -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