vmc 0.4.0.beta.8 → 0.4.0.beta.9
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/{vmc-ng/LICENSE → LICENSE} +0 -0
- data/{vmc-ng/Rakefile → Rakefile} +0 -0
- data/bin/vmc +10 -11
- data/{vmc-ng/lib → lib}/vmc/cli/app.rb +106 -58
- data/{vmc-ng/lib → lib}/vmc/cli/better_help.rb +0 -0
- data/{vmc-ng/lib → lib}/vmc/cli/command.rb +14 -0
- data/{vmc-ng/lib → lib}/vmc/cli/dots.rb +0 -0
- data/{vmc-ng/lib → lib}/vmc/cli/service.rb +0 -0
- data/{vmc-ng/lib → lib}/vmc/cli/user.rb +0 -0
- data/{vmc-ng/lib → lib}/vmc/cli.rb +88 -2
- data/{vmc-ng/lib → lib}/vmc/constants.rb +0 -0
- data/{vmc-ng/lib → lib}/vmc/detect.rb +0 -0
- data/{vmc-ng/lib → lib}/vmc/errors.rb +0 -0
- data/{vmc-ng/lib → lib}/vmc/plugin.rb +0 -0
- data/lib/vmc/version.rb +3 -0
- data/{vmc-ng/lib → lib}/vmc.rb +0 -0
- metadata +41 -273
- data/vmc/LICENSE +0 -24
- data/vmc/README.md +0 -102
- data/vmc/Rakefile +0 -101
- data/vmc/bin/vmc +0 -6
- data/vmc/caldecott_helper/Gemfile +0 -10
- data/vmc/caldecott_helper/Gemfile.lock +0 -48
- data/vmc/caldecott_helper/server.rb +0 -43
- data/vmc/config/clients.yml +0 -17
- data/vmc/config/micro/offline.conf +0 -2
- data/vmc/config/micro/paths.yml +0 -22
- data/vmc/config/micro/refresh_ip.rb +0 -20
- data/vmc/lib/cli/commands/admin.rb +0 -80
- data/vmc/lib/cli/commands/apps.rb +0 -1126
- data/vmc/lib/cli/commands/base.rb +0 -227
- data/vmc/lib/cli/commands/manifest.rb +0 -56
- data/vmc/lib/cli/commands/micro.rb +0 -115
- data/vmc/lib/cli/commands/misc.rb +0 -129
- data/vmc/lib/cli/commands/services.rb +0 -180
- data/vmc/lib/cli/commands/user.rb +0 -65
- data/vmc/lib/cli/config.rb +0 -173
- data/vmc/lib/cli/console_helper.rb +0 -160
- data/vmc/lib/cli/core_ext.rb +0 -122
- data/vmc/lib/cli/errors.rb +0 -19
- data/vmc/lib/cli/frameworks.rb +0 -265
- data/vmc/lib/cli/manifest_helper.rb +0 -302
- data/vmc/lib/cli/runner.rb +0 -531
- data/vmc/lib/cli/services_helper.rb +0 -84
- data/vmc/lib/cli/tunnel_helper.rb +0 -332
- data/vmc/lib/cli/usage.rb +0 -115
- data/vmc/lib/cli/version.rb +0 -7
- data/vmc/lib/cli/zip_util.rb +0 -77
- data/vmc/lib/cli.rb +0 -47
- data/vmc/lib/vmc/client.rb +0 -471
- data/vmc/lib/vmc/const.rb +0 -22
- data/vmc/lib/vmc/micro/switcher/base.rb +0 -97
- data/vmc/lib/vmc/micro/switcher/darwin.rb +0 -19
- data/vmc/lib/vmc/micro/switcher/dummy.rb +0 -15
- data/vmc/lib/vmc/micro/switcher/linux.rb +0 -16
- data/vmc/lib/vmc/micro/switcher/windows.rb +0 -31
- data/vmc/lib/vmc/micro/vmrun.rb +0 -158
- data/vmc/lib/vmc/micro.rb +0 -56
- data/vmc/lib/vmc.rb +0 -3
- data/vmc-ng/bin/vmc +0 -14
- data/vmc-ng/lib/vmc/version.rb +0 -3
data/vmc/lib/vmc/client.rb
DELETED
@@ -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
|
data/vmc/lib/vmc/const.rb
DELETED
@@ -1,22 +0,0 @@
|
|
1
|
-
module VMC
|
2
|
-
|
3
|
-
# This is the internal VMC version number, and is not necessarily
|
4
|
-
# the same as the RubyGem version (VMC::Cli::VERSION).
|
5
|
-
VERSION = '0.3.2'
|
6
|
-
|
7
|
-
# Targets
|
8
|
-
DEFAULT_TARGET = 'https://api.cloudfoundry.com'
|
9
|
-
DEFAULT_LOCAL_TARGET = 'http://api.vcap.me'
|
10
|
-
|
11
|
-
# General Paths
|
12
|
-
INFO_PATH = 'info'
|
13
|
-
GLOBAL_SERVICES_PATH = ['info', 'services']
|
14
|
-
GLOBAL_RUNTIMES_PATH = ['info', 'runtimes']
|
15
|
-
RESOURCES_PATH = 'resources'
|
16
|
-
|
17
|
-
# User specific paths
|
18
|
-
APPS_PATH = 'apps'
|
19
|
-
SERVICES_PATH = 'services'
|
20
|
-
USERS_PATH = 'users'
|
21
|
-
|
22
|
-
end
|
@@ -1,97 +0,0 @@
|
|
1
|
-
require 'interact'
|
2
|
-
|
3
|
-
module VMC::Micro::Switcher
|
4
|
-
class Base
|
5
|
-
include Interactive
|
6
|
-
|
7
|
-
def initialize(config)
|
8
|
-
@config = config
|
9
|
-
|
10
|
-
@vmrun = VMC::Micro::VMrun.new(config)
|
11
|
-
unless @vmrun.running?
|
12
|
-
if ask("Micro Cloud Foundry VM is not running. Do you want to start it?", :choices => ['y', 'n']) == 'y'
|
13
|
-
display "Starting Micro Cloud Foundry VM: ", false
|
14
|
-
@vmrun.start
|
15
|
-
say "done".green
|
16
|
-
else
|
17
|
-
err "Micro Cloud Foundry VM needs to be running."
|
18
|
-
end
|
19
|
-
end
|
20
|
-
|
21
|
-
err "Micro Cloud Foundry VM initial setup needs to be completed before using 'vmc micro'" unless @vmrun.ready?
|
22
|
-
end
|
23
|
-
|
24
|
-
def offline
|
25
|
-
unless @vmrun.offline?
|
26
|
-
# save online connection type so we can restore it later
|
27
|
-
@config['online_connection_type'] = @vmrun.connection_type
|
28
|
-
|
29
|
-
if (@config['online_connection_type'] != 'nat')
|
30
|
-
if ask("Reconfigure Micro Cloud Foundry VM network to nat mode and reboot?", :choices => ['y', 'n']) == 'y'
|
31
|
-
display "Rebooting Micro Cloud Foundry VM: ", false
|
32
|
-
@vmrun.connection_type = 'nat'
|
33
|
-
@vmrun.reset
|
34
|
-
say "done".green
|
35
|
-
else
|
36
|
-
err "Aborted"
|
37
|
-
end
|
38
|
-
end
|
39
|
-
|
40
|
-
display "Setting Micro Cloud Foundry VM to offline mode: ", false
|
41
|
-
@vmrun.offline!
|
42
|
-
say "done".green
|
43
|
-
display "Setting host DNS server: ", false
|
44
|
-
|
45
|
-
@config['domain'] = @vmrun.domain
|
46
|
-
@config['ip'] = @vmrun.ip
|
47
|
-
set_nameserver(@config['domain'], @config['ip'])
|
48
|
-
say "done".green
|
49
|
-
else
|
50
|
-
say "Micro Cloud Foundry VM already in offline mode".yellow
|
51
|
-
end
|
52
|
-
end
|
53
|
-
|
54
|
-
def online
|
55
|
-
if @vmrun.offline?
|
56
|
-
current_connection_type = @vmrun.connection_type
|
57
|
-
@config['online_connection_type'] ||= current_connection_type
|
58
|
-
|
59
|
-
if (@config['online_connection_type'] != current_connection_type)
|
60
|
-
# TODO handle missing connection type in saved config
|
61
|
-
question = "Reconfigure Micro Cloud Foundry VM network to #{@config['online_connection_type']} mode and reboot?"
|
62
|
-
if ask(question, :choices => ['y', 'n']) == 'y'
|
63
|
-
display "Rebooting Micro Cloud Foundry VM: ", false
|
64
|
-
@vmrun.connection_type = @config['online_connection_type']
|
65
|
-
@vmrun.reset
|
66
|
-
say "done".green
|
67
|
-
else
|
68
|
-
err "Aborted"
|
69
|
-
end
|
70
|
-
end
|
71
|
-
|
72
|
-
display "Unsetting host DNS server: ", false
|
73
|
-
# TODO handle missing domain and ip in saved config (look at the VM)
|
74
|
-
@config['domain'] ||= @vmrun.domain
|
75
|
-
@config['ip'] ||= @vmrun.ip
|
76
|
-
unset_nameserver(@config['domain'], @config['ip'])
|
77
|
-
say "done".green
|
78
|
-
|
79
|
-
display "Setting Micro Cloud Foundry VM to online mode: ", false
|
80
|
-
@vmrun.online!
|
81
|
-
say "done".green
|
82
|
-
else
|
83
|
-
say "Micro Cloud Foundry already in online mode".yellow
|
84
|
-
end
|
85
|
-
end
|
86
|
-
|
87
|
-
def status
|
88
|
-
mode = @vmrun.offline? ? 'offline' : 'online'
|
89
|
-
say "Micro Cloud Foundry VM currently in #{mode.green} mode"
|
90
|
-
# should the VMX path be unescaped?
|
91
|
-
say "VMX Path: #{@vmrun.vmx}"
|
92
|
-
say "Domain: #{@vmrun.domain.green}"
|
93
|
-
say "IP Address: #{@vmrun.ip.green}"
|
94
|
-
end
|
95
|
-
end
|
96
|
-
|
97
|
-
end
|
@@ -1,19 +0,0 @@
|
|
1
|
-
module VMC::Micro::Switcher
|
2
|
-
|
3
|
-
class Darwin < Base
|
4
|
-
def adminrun(command)
|
5
|
-
VMC::Micro.run_command("osascript", "-e 'do shell script \"#{command}\" with administrator privileges'")
|
6
|
-
end
|
7
|
-
|
8
|
-
def set_nameserver(domain, ip)
|
9
|
-
File.open("/tmp/#{domain}", 'w') { |file| file.write("nameserver #{ip}") }
|
10
|
-
adminrun("mkdir -p /etc/resolver;mv /tmp/#{domain} /etc/resolver/")
|
11
|
-
end
|
12
|
-
|
13
|
-
def unset_nameserver(domain, ip)
|
14
|
-
err "domain missing" unless domain
|
15
|
-
adminrun("rm -f /etc/resolver/#{domain}")
|
16
|
-
end
|
17
|
-
end
|
18
|
-
|
19
|
-
end
|
@@ -1,16 +0,0 @@
|
|
1
|
-
module VMC::Micro::Switcher
|
2
|
-
|
3
|
-
class Linux < Base
|
4
|
-
def set_nameserver(domain, ip)
|
5
|
-
VMC::Micro.run_command("sudo", "sed -i'.backup' '1 i nameserver #{ip}' /etc/resolv.conf")
|
6
|
-
# lock resolv.conf so Network Manager doesn't clear out the file when offline
|
7
|
-
VMC::Micro.run_command("sudo", "chattr +i /etc/resolv.conf")
|
8
|
-
end
|
9
|
-
|
10
|
-
def unset_nameserver(domain, ip)
|
11
|
-
VMC::Micro.run_command("sudo", "chattr -i /etc/resolv.conf")
|
12
|
-
VMC::Micro.run_command("sudo", "sed -i'.backup' '/#{ip}/d' /etc/resolv.conf")
|
13
|
-
end
|
14
|
-
end
|
15
|
-
|
16
|
-
end
|
@@ -1,31 +0,0 @@
|
|
1
|
-
module VMC::Micro::Switcher
|
2
|
-
|
3
|
-
class Windows < Base
|
4
|
-
def version?
|
5
|
-
VMC::Micro.run_command("cmd", "/c ver").to_s.scan(/\d+\.\d+/).first.to_f
|
6
|
-
end
|
7
|
-
|
8
|
-
def adminrun(command, args=nil)
|
9
|
-
if version? > 5.2
|
10
|
-
require 'win32ole'
|
11
|
-
shell = WIN32OLE.new("Shell.Application")
|
12
|
-
shell.ShellExecute(command, args, nil, "runas", 0)
|
13
|
-
else
|
14
|
-
# on older version this will try to run the command, and if you don't have
|
15
|
-
# admin privilges it will tell you so and exit
|
16
|
-
VMC::Micro.run_command(command, args)
|
17
|
-
end
|
18
|
-
end
|
19
|
-
|
20
|
-
# TODO better method to figure out the interface name is to get the NAT ip and find the
|
21
|
-
# interface with the correct subnet
|
22
|
-
def set_nameserver(domain, ip)
|
23
|
-
adminrun("netsh", "interface ip set dns \"VMware Network Adapter VMnet8\" static #{ip}")
|
24
|
-
end
|
25
|
-
|
26
|
-
def unset_nameserver(domain, ip)
|
27
|
-
adminrun("netsh", "interface ip set dns \"VMware Network Adapter VMnet8\" static none")
|
28
|
-
end
|
29
|
-
end
|
30
|
-
|
31
|
-
end
|