vmc 0.4.0.beta.5 → 0.4.0.beta.6

Sign up to get free protection for your applications and to get access to all the features.
Files changed (61) hide show
  1. data/{vmc-ng/LICENSE → LICENSE} +0 -0
  2. data/{vmc-ng/Rakefile → Rakefile} +0 -0
  3. data/bin/vmc +10 -11
  4. data/{vmc-ng/lib → lib}/vmc.rb +0 -0
  5. data/{vmc-ng/lib → lib}/vmc/cli.rb +17 -9
  6. data/{vmc-ng/lib → lib}/vmc/cli/app.rb +31 -31
  7. data/{vmc-ng/lib → lib}/vmc/cli/better_help.rb +0 -0
  8. data/{vmc-ng/lib → lib}/vmc/cli/command.rb +6 -6
  9. data/{vmc-ng/lib → lib}/vmc/cli/dots.rb +63 -8
  10. data/{vmc-ng/lib → lib}/vmc/cli/service.rb +6 -6
  11. data/{vmc-ng/lib → lib}/vmc/cli/user.rb +2 -2
  12. data/{vmc-ng/lib → lib}/vmc/constants.rb +1 -0
  13. data/{vmc-ng/lib → lib}/vmc/detect.rb +0 -0
  14. data/{vmc-ng/lib → lib}/vmc/errors.rb +0 -0
  15. data/{vmc-ng/lib → lib}/vmc/plugin.rb +0 -0
  16. data/lib/vmc/version.rb +3 -0
  17. metadata +33 -281
  18. data/vmc-ng/bin/vmc +0 -14
  19. data/vmc-ng/lib/vmc/version.rb +0 -3
  20. data/vmc/LICENSE +0 -24
  21. data/vmc/README.md +0 -102
  22. data/vmc/Rakefile +0 -101
  23. data/vmc/bin/vmc +0 -6
  24. data/vmc/caldecott_helper/Gemfile +0 -10
  25. data/vmc/caldecott_helper/Gemfile.lock +0 -48
  26. data/vmc/caldecott_helper/server.rb +0 -43
  27. data/vmc/config/clients.yml +0 -17
  28. data/vmc/config/micro/offline.conf +0 -2
  29. data/vmc/config/micro/paths.yml +0 -22
  30. data/vmc/config/micro/refresh_ip.rb +0 -20
  31. data/vmc/lib/cli.rb +0 -47
  32. data/vmc/lib/cli/commands/admin.rb +0 -80
  33. data/vmc/lib/cli/commands/apps.rb +0 -1126
  34. data/vmc/lib/cli/commands/base.rb +0 -227
  35. data/vmc/lib/cli/commands/manifest.rb +0 -56
  36. data/vmc/lib/cli/commands/micro.rb +0 -115
  37. data/vmc/lib/cli/commands/misc.rb +0 -129
  38. data/vmc/lib/cli/commands/services.rb +0 -180
  39. data/vmc/lib/cli/commands/user.rb +0 -65
  40. data/vmc/lib/cli/config.rb +0 -173
  41. data/vmc/lib/cli/console_helper.rb +0 -160
  42. data/vmc/lib/cli/core_ext.rb +0 -122
  43. data/vmc/lib/cli/errors.rb +0 -19
  44. data/vmc/lib/cli/frameworks.rb +0 -265
  45. data/vmc/lib/cli/manifest_helper.rb +0 -302
  46. data/vmc/lib/cli/runner.rb +0 -531
  47. data/vmc/lib/cli/services_helper.rb +0 -84
  48. data/vmc/lib/cli/tunnel_helper.rb +0 -332
  49. data/vmc/lib/cli/usage.rb +0 -115
  50. data/vmc/lib/cli/version.rb +0 -7
  51. data/vmc/lib/cli/zip_util.rb +0 -77
  52. data/vmc/lib/vmc.rb +0 -3
  53. data/vmc/lib/vmc/client.rb +0 -471
  54. data/vmc/lib/vmc/const.rb +0 -22
  55. data/vmc/lib/vmc/micro.rb +0 -56
  56. data/vmc/lib/vmc/micro/switcher/base.rb +0 -97
  57. data/vmc/lib/vmc/micro/switcher/darwin.rb +0 -19
  58. data/vmc/lib/vmc/micro/switcher/dummy.rb +0 -15
  59. data/vmc/lib/vmc/micro/switcher/linux.rb +0 -16
  60. data/vmc/lib/vmc/micro/switcher/windows.rb +0 -31
  61. data/vmc/lib/vmc/micro/vmrun.rb +0 -158
@@ -1,7 +0,0 @@
1
- module VMC
2
- module Cli
3
- # This version number is used as the RubyGem release version.
4
- # The internal VMC version number is VMC::VERSION.
5
- VERSION = '0.3.18'
6
- end
7
- end
@@ -1,77 +0,0 @@
1
-
2
- require 'zip/zipfilesystem'
3
-
4
- module VMC::Cli
5
-
6
- class ZipUtil
7
-
8
- PACK_EXCLUSION_GLOBS = ['..', '.', '*~', '#*#', '*.log']
9
-
10
- class << self
11
-
12
- def to_dev_null
13
- if WINDOWS
14
- 'nul'
15
- else
16
- '/dev/null'
17
- end
18
- end
19
-
20
- def entry_lines(file)
21
- contents = nil
22
- unless VMC::Cli::Config.nozip
23
- contents = `unzip -l #{file} 2> #{to_dev_null}`
24
- contents = nil if $? != 0
25
- end
26
- # Do Ruby version if told to or native version failed
27
- unless contents
28
- entries = []
29
- Zip::ZipFile.foreach(file) { |zentry| entries << zentry }
30
- contents = entries.join("\n")
31
- end
32
- contents
33
- end
34
-
35
- def unpack(file, dest)
36
- unless VMC::Cli::Config.nozip
37
- FileUtils.mkdir(dest)
38
- `unzip -q #{file} -d #{dest} 2> #{to_dev_null}`
39
- return unless $? != 0
40
- end
41
- # Do Ruby version if told to or native version failed
42
- Zip::ZipFile.foreach(file) do |zentry|
43
- epath = "#{dest}/#{zentry}"
44
- dirname = File.dirname(epath)
45
- FileUtils.mkdir_p(dirname) unless File.exists?(dirname)
46
- zentry.extract(epath) unless File.exists?(epath)
47
- end
48
- end
49
-
50
- def get_files_to_pack(dir)
51
- Dir.glob("#{dir}/**/*", File::FNM_DOTMATCH).select do |f|
52
- process = true
53
- PACK_EXCLUSION_GLOBS.each { |e| process = false if File.fnmatch(e, File.basename(f)) }
54
- process && File.exists?(f)
55
- end
56
- end
57
-
58
- def pack(dir, zipfile)
59
- unless VMC::Cli::Config.nozip
60
- excludes = PACK_EXCLUSION_GLOBS.map { |e| "\\#{e}" }
61
- excludes = excludes.join(' ')
62
- Dir.chdir(dir) do
63
- `zip -y -q -r #{zipfile} . -x #{excludes} 2> #{to_dev_null}`
64
- return unless $? != 0
65
- end
66
- end
67
- # Do Ruby version if told to or native version failed
68
- Zip::ZipFile::open(zipfile, true) do |zf|
69
- get_files_to_pack(dir).each do |f|
70
- zf.add(f.sub("#{dir}/",''), f)
71
- end
72
- end
73
- end
74
-
75
- end
76
- end
77
- end
@@ -1,3 +0,0 @@
1
- module VMC; end
2
-
3
- require 'vmc/client'
@@ -1,471 +0,0 @@
1
- # VMC client
2
- #
3
- # Example:
4
- #
5
- # require 'vmc'
6
- # client = VMC::Client.new('api.vcap.me')
7
- # client.login(:user, :pass)
8
- # client.create('myapplication', manifest)
9
- # client.create_service('redis', 'my_redis_service', opts);
10
- #
11
-
12
- require 'rubygems'
13
- require 'json/pure'
14
- require 'open-uri'
15
-
16
- require File.expand_path('../const', __FILE__)
17
-
18
- class VMC::Client
19
-
20
- def self.version
21
- VMC::VERSION
22
- end
23
-
24
- attr_reader :target, :host, :user, :proxy, :auth_token
25
- attr_accessor :trace
26
-
27
- # Error codes
28
- VMC_HTTP_ERROR_CODES = [ 400, 500 ]
29
-
30
- # Errors
31
- class BadTarget < RuntimeError; end
32
- class AuthError < RuntimeError; end
33
- class TargetError < RuntimeError; end
34
- class NotFound < RuntimeError; end
35
- class BadResponse < RuntimeError; end
36
- class HTTPException < RuntimeError; end
37
-
38
- # Initialize new client to the target_uri with optional auth_token
39
- def initialize(target_url=VMC::DEFAULT_TARGET, auth_token=nil)
40
- target_url = "http://#{target_url}" unless /^https?/ =~ target_url
41
- target_url = target_url.gsub(/\/+$/, '')
42
- @target = target_url
43
- @auth_token = auth_token
44
- end
45
-
46
- ######################################################
47
- # Target info
48
- ######################################################
49
-
50
- # Retrieves information on the target cloud, and optionally the logged in user
51
- def info
52
- # TODO: Should merge for new version IMO, general, services, user_account
53
- json_get(VMC::INFO_PATH)
54
- end
55
-
56
- def raw_info
57
- http_get(VMC::INFO_PATH)
58
- end
59
-
60
- # Global listing of services that are available on the target system
61
- def services_info
62
- check_login_status
63
- json_get(path(VMC::GLOBAL_SERVICES_PATH))
64
- end
65
-
66
- def runtimes_info
67
- json_get(path(VMC::GLOBAL_RUNTIMES_PATH))
68
- end
69
-
70
- ######################################################
71
- # Apps
72
- ######################################################
73
-
74
- def apps
75
- check_login_status
76
- json_get(VMC::APPS_PATH)
77
- end
78
-
79
- def create_app(name, manifest={})
80
- check_login_status
81
- app = manifest.dup
82
- app[:name] = name
83
- app[:instances] ||= 1
84
- json_post(VMC::APPS_PATH, app)
85
- end
86
-
87
- def update_app(name, manifest)
88
- check_login_status
89
- json_put(path(VMC::APPS_PATH, name), manifest)
90
- end
91
-
92
- def upload_app(name, zipfile, resource_manifest=nil)
93
- #FIXME, manifest should be allowed to be null, here for compatability with old cc's
94
- resource_manifest ||= []
95
- check_login_status
96
- upload_data = {:_method => 'put'}
97
- if zipfile
98
- if zipfile.is_a? File
99
- file = zipfile
100
- else
101
- file = File.new(zipfile, 'rb')
102
- end
103
- upload_data[:application] = file
104
- end
105
- upload_data[:resources] = resource_manifest.to_json if resource_manifest
106
- http_post(path(VMC::APPS_PATH, name, "application"), upload_data)
107
- rescue RestClient::ServerBrokeConnection
108
- retry
109
- end
110
-
111
- def delete_app(name)
112
- check_login_status
113
- http_delete(path(VMC::APPS_PATH, name))
114
- end
115
-
116
- def app_info(name)
117
- check_login_status
118
- json_get(path(VMC::APPS_PATH, name))
119
- end
120
-
121
- def app_update_info(name)
122
- check_login_status
123
- json_get(path(VMC::APPS_PATH, name, "update"))
124
- end
125
-
126
- def app_stats(name)
127
- check_login_status
128
- stats_raw = json_get(path(VMC::APPS_PATH, name, "stats"))
129
- stats = []
130
- stats_raw.each_pair do |k, entry|
131
- # Skip entries with no stats
132
- next unless entry[:stats]
133
- entry[:instance] = k.to_s.to_i
134
- entry[:state] = entry[:state].to_sym if entry[:state]
135
- stats << entry
136
- end
137
- stats.sort { |a,b| a[:instance] - b[:instance] }
138
- end
139
-
140
- def app_instances(name)
141
- check_login_status
142
- json_get(path(VMC::APPS_PATH, name, "instances"))
143
- end
144
-
145
- def app_crashes(name)
146
- check_login_status
147
- json_get(path(VMC::APPS_PATH, name, "crashes"))
148
- end
149
-
150
- # List the directory or download the actual file indicated by
151
- # the path.
152
- def app_files(name, path, instance='0')
153
- check_login_status
154
- path = path.gsub('//', '/')
155
- url = path(VMC::APPS_PATH, name, "instances", instance, "files", path)
156
- _, body, headers = http_get(url)
157
- body
158
- end
159
-
160
- ######################################################
161
- # Services
162
- ######################################################
163
-
164
- # listing of services that are available in the system
165
- def services
166
- check_login_status
167
- json_get(VMC::SERVICES_PATH)
168
- end
169
-
170
- def create_service(service, name)
171
- check_login_status
172
- services = services_info
173
- services ||= []
174
- service_hash = nil
175
-
176
- service = service.to_s
177
-
178
- # FIXME!
179
- services.each do |service_type, value|
180
- value.each do |vendor, version|
181
- version.each do |version_str, service_descr|
182
- if service == service_descr[:vendor]
183
- service_hash = {
184
- :type => service_descr[:type], :tier => 'free',
185
- :vendor => service, :version => version_str
186
- }
187
- break
188
- end
189
- end
190
- end
191
- end
192
-
193
- raise TargetError, "Service [#{service}] is not a valid service choice" unless service_hash
194
- service_hash[:name] = name
195
- json_post(path(VMC::SERVICES_PATH), service_hash)
196
- end
197
-
198
- def delete_service(name)
199
- check_login_status
200
- svcs = services || []
201
- names = svcs.collect { |s| s[:name] }
202
- raise TargetError, "Service [#{name}] not a valid service" unless names.include? name
203
- http_delete(path(VMC::SERVICES_PATH, name))
204
- end
205
-
206
- def bind_service(service, appname)
207
- check_login_status
208
- app = app_info(appname)
209
- services = app[:services] || []
210
- app[:services] = services << service
211
- update_app(appname, app)
212
- end
213
-
214
- def unbind_service(service, appname)
215
- check_login_status
216
- app = app_info(appname)
217
- services = app[:services] || []
218
- services.delete(service)
219
- app[:services] = services
220
- update_app(appname, app)
221
- end
222
-
223
- ######################################################
224
- # Resources
225
- ######################################################
226
-
227
- # Send in a resources manifest array to the system to have
228
- # it check what is needed to actually send. Returns array
229
- # indicating what is needed. This returned manifest should be
230
- # sent in with the upload if resources were removed.
231
- # E.g. [{:sha1 => xxx, :size => xxx, :fn => filename}]
232
- def check_resources(resources)
233
- check_login_status
234
- status, body, headers = json_post(VMC::RESOURCES_PATH, resources)
235
- json_parse(body)
236
- end
237
-
238
- ######################################################
239
- # Validation Helpers
240
- ######################################################
241
-
242
- # Checks that the target is valid
243
- def target_valid?
244
- return false unless descr = info
245
- return false unless descr[:name]
246
- return false unless descr[:build]
247
- return false unless descr[:version]
248
- return false unless descr[:support]
249
- true
250
- rescue
251
- false
252
- end
253
-
254
- # Checks that the auth_token is valid
255
- def logged_in?
256
- descr = info
257
- if descr
258
- return false unless descr[:user]
259
- return false unless descr[:usage]
260
- @user = descr[:user]
261
- true
262
- end
263
- end
264
-
265
- ######################################################
266
- # User login/password
267
- ######################################################
268
-
269
- # login and return an auth_token
270
- # Auth token can be retained and used in creating
271
- # new clients, avoiding login.
272
- def login(user, password)
273
- status, body, headers = json_post(path(VMC::USERS_PATH, user, "tokens"), {:password => password})
274
- response_info = json_parse(body)
275
- if response_info
276
- @user = user
277
- @auth_token = response_info[:token]
278
- end
279
- end
280
-
281
- # sets the password for the current logged user
282
- def change_password(new_password)
283
- check_login_status
284
- user_info = json_get(path(VMC::USERS_PATH, @user))
285
- if user_info
286
- user_info[:password] = new_password
287
- json_put(path(VMC::USERS_PATH, @user), user_info)
288
- end
289
- end
290
-
291
- ######################################################
292
- # System administration
293
- ######################################################
294
-
295
- def proxy=(proxy)
296
- @proxy = proxy
297
- end
298
-
299
- def proxy_for(proxy)
300
- @proxy = proxy
301
- end
302
-
303
- def users
304
- check_login_status
305
- json_get(VMC::USERS_PATH)
306
- end
307
-
308
- def add_user(user_email, password)
309
- json_post(VMC::USERS_PATH, { :email => user_email, :password => password })
310
- end
311
-
312
- def delete_user(user_email)
313
- check_login_status
314
- http_delete(path(VMC::USERS_PATH, user_email))
315
- end
316
-
317
- ######################################################
318
-
319
- def self.path(*path)
320
- path.flatten.collect { |x|
321
- URI.encode x.to_s, Regexp.new("[^#{URI::PATTERN::UNRESERVED}]")
322
- }.join("/")
323
- end
324
-
325
- private
326
-
327
- def path(*args, &blk)
328
- self.class.path(*args, &blk)
329
- end
330
-
331
- def json_get(url)
332
- status, body, headers = http_get(url, 'application/json')
333
- json_parse(body)
334
- rescue JSON::ParserError
335
- raise BadResponse, "Can't parse response into JSON", body
336
- end
337
-
338
- def json_post(url, payload)
339
- http_post(url, payload.to_json, 'application/json')
340
- end
341
-
342
- def json_put(url, payload)
343
- http_put(url, payload.to_json, 'application/json')
344
- end
345
-
346
- def json_parse(str)
347
- if str
348
- JSON.parse(str, :symbolize_names => true)
349
- end
350
- end
351
-
352
- require 'rest_client'
353
-
354
- # HTTP helpers
355
-
356
- def http_get(path, content_type=nil)
357
- request(:get, path, content_type)
358
- end
359
-
360
- def http_post(path, body, content_type=nil)
361
- request(:post, path, content_type, body)
362
- end
363
-
364
- def http_put(path, body, content_type=nil)
365
- request(:put, path, content_type, body)
366
- end
367
-
368
- def http_delete(path)
369
- request(:delete, path)
370
- end
371
-
372
- def request(method, path, content_type = nil, payload = nil, headers = {})
373
- headers = headers.dup
374
- headers['AUTHORIZATION'] = @auth_token if @auth_token
375
- headers['PROXY-USER'] = @proxy if @proxy
376
-
377
- if content_type
378
- headers['Content-Type'] = content_type
379
- headers['Accept'] = content_type
380
- end
381
-
382
- req = {
383
- :method => method, :url => "#{@target}/#{path}",
384
- :payload => payload, :headers => headers, :multipart => true
385
- }
386
- status, body, response_headers = perform_http_request(req)
387
-
388
- if request_failed?(status)
389
- # FIXME, old cc returned 400 on not found for file access
390
- err = (status == 404 || status == 400) ? NotFound : TargetError
391
- raise err, parse_error_message(status, body)
392
- else
393
- return status, body, response_headers
394
- end
395
- rescue URI::Error, SocketError, Errno::ECONNREFUSED => e
396
- raise BadTarget, "Cannot access target (%s)" % [ e.message ]
397
- end
398
-
399
- def request_failed?(status)
400
- VMC_HTTP_ERROR_CODES.detect{|error_code| status >= error_code}
401
- end
402
-
403
- def perform_http_request(req)
404
- proxy_uri = URI.parse(req[:url]).find_proxy()
405
- RestClient.proxy = proxy_uri.to_s if proxy_uri
406
-
407
- # Setup tracing if needed
408
- unless trace.nil?
409
- req[:headers]['X-VCAP-Trace'] = (trace == true ? '22' : trace)
410
- end
411
-
412
- result = nil
413
- RestClient::Request.execute(req) do |response, request|
414
- result = [ response.code, response.body, response.headers ]
415
- unless trace.nil?
416
- puts '>>>'
417
- puts "PROXY: #{RestClient.proxy}" if RestClient.proxy
418
- puts "REQUEST: #{req[:method]} #{req[:url]}"
419
- puts "RESPONSE_HEADERS:"
420
- response.headers.each do |key, value|
421
- puts " #{key} : #{value}"
422
- end
423
- puts "REQUEST_BODY: #{req[:payload]}" if req[:payload]
424
- puts "RESPONSE: [#{response.code}]"
425
- begin
426
- puts JSON.pretty_generate(JSON.parse(response.body))
427
- rescue
428
- puts "#{response.body}"
429
- end
430
- puts '<<<'
431
- end
432
- end
433
- result
434
- rescue Net::HTTPBadResponse => e
435
- raise BadTarget "Received bad HTTP response from target: #{e}"
436
- rescue SystemCallError, RestClient::Exception => e
437
- raise HTTPException, "HTTP exception: #{e.class}:#{e}"
438
- end
439
-
440
- def truncate(str, limit = 30)
441
- etc = '...'
442
- stripped = str.strip[0..limit]
443
- if stripped.length > limit
444
- stripped + etc
445
- else
446
- stripped
447
- end
448
- end
449
-
450
- def parse_error_message(status, body)
451
- parsed_body = json_parse(body.to_s)
452
- if parsed_body && parsed_body[:code] && parsed_body[:description]
453
- desc = parsed_body[:description].gsub("\"","'")
454
- "Error #{parsed_body[:code]}: #{desc}"
455
- else
456
- "Error (HTTP #{status}): #{body}"
457
- end
458
- rescue JSON::ParserError
459
- if body.nil? || body.empty?
460
- "Error (#{status}): No Response Received"
461
- else
462
- body_out = trace ? body : truncate(body)
463
- "Error (JSON #{status}): #{body_out}"
464
- end
465
- end
466
-
467
- def check_login_status
468
- raise AuthError unless @user || logged_in?
469
- end
470
-
471
- end