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,336 @@
|
|
1
|
+
# Copyright (c) 2009-2011 VMware, Inc.
|
2
|
+
|
3
|
+
require 'addressable/uri'
|
4
|
+
|
5
|
+
begin
|
6
|
+
require 'caldecott'
|
7
|
+
rescue LoadError
|
8
|
+
end
|
9
|
+
|
10
|
+
module VMC::Cli
|
11
|
+
module TunnelHelper
|
12
|
+
PORT_RANGE = 10
|
13
|
+
|
14
|
+
HELPER_APP = File.expand_path("../../../caldecott_helper", __FILE__)
|
15
|
+
|
16
|
+
# bump this AND the version info reported by HELPER_APP/server.rb
|
17
|
+
# this is to keep the helper in sync with any updates here
|
18
|
+
HELPER_VERSION = '0.0.4'
|
19
|
+
|
20
|
+
def tunnel_uniquename(infra)
|
21
|
+
random_service_name(tunnel_appname(infra))
|
22
|
+
end
|
23
|
+
|
24
|
+
def tunnel_appname(infra)
|
25
|
+
infra ? "caldecott-#{infra}" : "caldecott"
|
26
|
+
end
|
27
|
+
|
28
|
+
def tunnel_app_info(infra)
|
29
|
+
begin
|
30
|
+
client.app_info(tunnel_appname(infra))
|
31
|
+
rescue => e
|
32
|
+
nil
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def tunnel_auth(infra)
|
37
|
+
tunnel_app_info(infra)[:env].each do |e|
|
38
|
+
name, val = e.split("=", 2)
|
39
|
+
return val if name == "CALDECOTT_AUTH"
|
40
|
+
end
|
41
|
+
nil
|
42
|
+
end
|
43
|
+
|
44
|
+
def tunnel_url(infra)
|
45
|
+
|
46
|
+
tun_url = tunnel_app_info(infra)[:uris][0]
|
47
|
+
|
48
|
+
["https", "http"].each do |scheme|
|
49
|
+
url = "#{scheme}://#{tun_url}"
|
50
|
+
begin
|
51
|
+
RestClient.get(url)
|
52
|
+
|
53
|
+
# https failed
|
54
|
+
rescue Errno::ECONNREFUSED
|
55
|
+
|
56
|
+
# we expect a 404 since this request isn't auth'd
|
57
|
+
rescue RestClient::ResourceNotFound
|
58
|
+
return url
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
err "Cannot determine URL for #{tun_url}"
|
63
|
+
end
|
64
|
+
|
65
|
+
def invalidate_tunnel_app_info(infra)
|
66
|
+
end
|
67
|
+
|
68
|
+
def tunnel_pushed?(infra)
|
69
|
+
not tunnel_app_info(infra).nil?
|
70
|
+
end
|
71
|
+
|
72
|
+
def tunnel_healthy?(token,infra)
|
73
|
+
return false unless tunnel_app_info(infra)[:state] == 'STARTED'
|
74
|
+
|
75
|
+
begin
|
76
|
+
response = RestClient.get(
|
77
|
+
"#{tunnel_url(infra)}/info",
|
78
|
+
"Auth-Token" => token
|
79
|
+
)
|
80
|
+
info = JSON.parse(response)
|
81
|
+
if info["version"] == HELPER_VERSION
|
82
|
+
true
|
83
|
+
else
|
84
|
+
stop_caldecott(infra)
|
85
|
+
false
|
86
|
+
end
|
87
|
+
rescue RestClient::Exception
|
88
|
+
stop_caldecott(infra)
|
89
|
+
false
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
def tunnel_bound?(service,infra)
|
94
|
+
tunnel_app_info(infra)[:services].include?(service)
|
95
|
+
end
|
96
|
+
|
97
|
+
def tunnel_connection_info(type, service, token, infra)
|
98
|
+
display "Getting tunnel connection info: ", false
|
99
|
+
response = nil
|
100
|
+
10.times do
|
101
|
+
begin
|
102
|
+
response = RestClient.get(tunnel_url(infra) + "/" + VMC::Client.path("services", service), "Auth-Token" => token)
|
103
|
+
break
|
104
|
+
rescue RestClient::Exception => e
|
105
|
+
puts "Error infra: #{infra}, url: #{tunnel_url(infra)}"
|
106
|
+
display tunnel_url(infra)
|
107
|
+
puts e.message.red
|
108
|
+
sleep 1
|
109
|
+
end
|
110
|
+
|
111
|
+
display ".", false
|
112
|
+
end
|
113
|
+
|
114
|
+
unless response
|
115
|
+
err "Expected remote tunnel to know about #{service}, but it doesn't"
|
116
|
+
end
|
117
|
+
|
118
|
+
display "OK".green
|
119
|
+
|
120
|
+
info = JSON.parse(response)
|
121
|
+
info["infra"] = infra
|
122
|
+
case type
|
123
|
+
when "rabbitmq"
|
124
|
+
uri = Addressable::URI.parse info["url"]
|
125
|
+
info["hostname"] = uri.host
|
126
|
+
info["port"] = uri.port
|
127
|
+
info["vhost"] = uri.path[1..-1]
|
128
|
+
info["user"] = uri.user
|
129
|
+
info["password"] = uri.password
|
130
|
+
info.delete "url"
|
131
|
+
|
132
|
+
# we use "db" as the "name" for mongo
|
133
|
+
# existing "name" is junk
|
134
|
+
when "mongodb"
|
135
|
+
info["name"] = info["db"]
|
136
|
+
info.delete "db"
|
137
|
+
|
138
|
+
# our "name" is irrelevant for redis
|
139
|
+
when "redis"
|
140
|
+
info.delete "name"
|
141
|
+
end
|
142
|
+
|
143
|
+
['hostname', 'port', 'password'].each do |k|
|
144
|
+
err "Could not determine #{k} for #{service}" if info[k].nil?
|
145
|
+
end
|
146
|
+
|
147
|
+
info
|
148
|
+
end
|
149
|
+
|
150
|
+
def display_tunnel_connection_info(info)
|
151
|
+
display ''
|
152
|
+
display "Service connection info: "
|
153
|
+
|
154
|
+
to_show = [nil, nil, nil] # reserved for user, pass, db name
|
155
|
+
info.keys.each do |k|
|
156
|
+
case k
|
157
|
+
when "host", "hostname", "port", "node_id"
|
158
|
+
# skip
|
159
|
+
when "user", "username"
|
160
|
+
# prefer "username" over "user"
|
161
|
+
to_show[0] = k unless to_show[0] == "username"
|
162
|
+
when "password"
|
163
|
+
to_show[1] = k
|
164
|
+
when "name"
|
165
|
+
to_show[2] = k
|
166
|
+
else
|
167
|
+
to_show << k
|
168
|
+
end
|
169
|
+
end
|
170
|
+
to_show.compact!
|
171
|
+
|
172
|
+
align_len = to_show.collect(&:size).max + 1
|
173
|
+
|
174
|
+
to_show.each do |k|
|
175
|
+
# TODO: modify the server services rest call to have explicit knowledge
|
176
|
+
# about the items to return. It should return all of them if
|
177
|
+
# the service is unknown so that we don't have to do this weird
|
178
|
+
# filtering.
|
179
|
+
display " #{k.ljust align_len}: ", false
|
180
|
+
display "#{info[k]}".yellow
|
181
|
+
end
|
182
|
+
display ''
|
183
|
+
end
|
184
|
+
|
185
|
+
def start_tunnel(local_port, conn_info, auth, infra)
|
186
|
+
@local_tunnel_thread = Thread.new do
|
187
|
+
Caldecott::Client.start({
|
188
|
+
:local_port => local_port,
|
189
|
+
:tun_url => tunnel_url(infra),
|
190
|
+
:dst_host => conn_info['hostname'],
|
191
|
+
:dst_port => conn_info['port'],
|
192
|
+
:log_file => STDOUT,
|
193
|
+
:log_level => ENV["VMC_TUNNEL_DEBUG"] || "ERROR",
|
194
|
+
:auth_token => auth,
|
195
|
+
:quiet => true
|
196
|
+
})
|
197
|
+
end
|
198
|
+
|
199
|
+
at_exit { @local_tunnel_thread.kill }
|
200
|
+
end
|
201
|
+
|
202
|
+
|
203
|
+
|
204
|
+
def pick_tunnel_port(port)
|
205
|
+
original = port
|
206
|
+
|
207
|
+
PORT_RANGE.times do |n|
|
208
|
+
begin
|
209
|
+
TCPSocket.open('localhost', port)
|
210
|
+
port += 1
|
211
|
+
rescue
|
212
|
+
return port
|
213
|
+
end
|
214
|
+
end
|
215
|
+
|
216
|
+
grab_ephemeral_port
|
217
|
+
end
|
218
|
+
|
219
|
+
def grab_ephemeral_port
|
220
|
+
socket = TCPServer.new('0.0.0.0', 0)
|
221
|
+
socket.setsockopt(Socket::SOL_SOCKET, Socket::SO_REUSEADDR, true)
|
222
|
+
Socket.do_not_reverse_lookup = true
|
223
|
+
port = socket.addr[1]
|
224
|
+
socket.close
|
225
|
+
return port
|
226
|
+
end
|
227
|
+
|
228
|
+
def wait_for_tunnel_start(port)
|
229
|
+
10.times do |n|
|
230
|
+
begin
|
231
|
+
client = TCPSocket.open('localhost', port)
|
232
|
+
display '' if n > 0
|
233
|
+
client.close
|
234
|
+
return true
|
235
|
+
rescue => e
|
236
|
+
display "Waiting for local tunnel to become available", false if n == 0
|
237
|
+
display '.', false
|
238
|
+
sleep 1
|
239
|
+
end
|
240
|
+
end
|
241
|
+
err "Could not connect to local tunnel."
|
242
|
+
end
|
243
|
+
|
244
|
+
def wait_for_tunnel_end
|
245
|
+
display "Open another shell to run command-line clients or"
|
246
|
+
display "use a UI tool to connect using the displayed information."
|
247
|
+
display "Press Ctrl-C to exit..."
|
248
|
+
@local_tunnel_thread.join
|
249
|
+
end
|
250
|
+
|
251
|
+
def resolve_symbols(str, info, local_port)
|
252
|
+
str.gsub(/\$\{\s*([^\}]+)\s*\}/) do
|
253
|
+
case $1
|
254
|
+
when "host"
|
255
|
+
# TODO: determine proper host
|
256
|
+
"localhost"
|
257
|
+
when "port"
|
258
|
+
local_port
|
259
|
+
when "user", "username"
|
260
|
+
info["username"]
|
261
|
+
else
|
262
|
+
info[$1] || ask($1)
|
263
|
+
end
|
264
|
+
end
|
265
|
+
end
|
266
|
+
|
267
|
+
def start_local_prog(clients, command, info, port)
|
268
|
+
client = clients[File.basename(command)]
|
269
|
+
|
270
|
+
cmdline = "#{command} "
|
271
|
+
|
272
|
+
case client
|
273
|
+
when Hash
|
274
|
+
cmdline << resolve_symbols(client["command"], info, port)
|
275
|
+
client["environment"].each do |e|
|
276
|
+
if e =~ /([^=]+)=(["']?)([^"']*)\2/
|
277
|
+
ENV[$1] = resolve_symbols($3, info, port)
|
278
|
+
else
|
279
|
+
err "Invalid environment variable: #{e}"
|
280
|
+
end
|
281
|
+
end
|
282
|
+
when String
|
283
|
+
cmdline << resolve_symbols(client, info, port)
|
284
|
+
else
|
285
|
+
err "Unknown client info: #{client.inspect}."
|
286
|
+
end
|
287
|
+
|
288
|
+
display "Launching '#{cmdline}'"
|
289
|
+
display ''
|
290
|
+
|
291
|
+
system(cmdline)
|
292
|
+
end
|
293
|
+
|
294
|
+
def push_caldecott(token,infra)
|
295
|
+
manifest = {
|
296
|
+
:name => tunnel_appname(infra),
|
297
|
+
:staging => {:framework => "sinatra", :runtime => "ruby18" },
|
298
|
+
:uris => ["#{tunnel_uniquename(infra)}.#{client.base_for_infra(infra)}"],
|
299
|
+
:instances => 1,
|
300
|
+
:resources => {:memory => 64},
|
301
|
+
:env => ["CALDECOTT_AUTH=#{token}"]
|
302
|
+
}
|
303
|
+
manifest[:infra] = { :provider => infra } if infra
|
304
|
+
|
305
|
+
client.create_app(
|
306
|
+
tunnel_appname(infra),
|
307
|
+
manifest
|
308
|
+
)
|
309
|
+
|
310
|
+
apps_cmd.send(:upload_app_bits, tunnel_appname(infra), HELPER_APP, infra)
|
311
|
+
|
312
|
+
invalidate_tunnel_app_info(infra)
|
313
|
+
end
|
314
|
+
|
315
|
+
def stop_caldecott(infra)
|
316
|
+
apps_cmd.stop(tunnel_appname(infra))
|
317
|
+
|
318
|
+
invalidate_tunnel_app_info(infra)
|
319
|
+
end
|
320
|
+
|
321
|
+
def start_caldecott(infra)
|
322
|
+
apps_cmd.start(tunnel_appname(infra))
|
323
|
+
|
324
|
+
invalidate_tunnel_app_info(infra)
|
325
|
+
end
|
326
|
+
|
327
|
+
private
|
328
|
+
|
329
|
+
def apps_cmd
|
330
|
+
a = Command::Apps.new(@options)
|
331
|
+
a.client client
|
332
|
+
a
|
333
|
+
end
|
334
|
+
|
335
|
+
end
|
336
|
+
end
|
data/lib/cli/usage.rb
ADDED
@@ -0,0 +1,125 @@
|
|
1
|
+
class VMC::Cli::Runner
|
2
|
+
|
3
|
+
def basic_usage
|
4
|
+
"Usage: as [options] command [<args>] [command_options]\n" +
|
5
|
+
"Try 'as help [command]' or 'as help options' for more information."
|
6
|
+
end
|
7
|
+
|
8
|
+
def display_usage
|
9
|
+
if @usage
|
10
|
+
say @usage_error if @usage_error
|
11
|
+
say "Usage: #{@usage}"
|
12
|
+
return
|
13
|
+
elsif @verb_usage
|
14
|
+
say @verb_usage
|
15
|
+
return
|
16
|
+
end
|
17
|
+
say command_usage
|
18
|
+
end
|
19
|
+
|
20
|
+
def command_usage
|
21
|
+
<<-USAGE
|
22
|
+
|
23
|
+
#{basic_usage}
|
24
|
+
|
25
|
+
Currently available as commands are:
|
26
|
+
|
27
|
+
Getting Started
|
28
|
+
target [url] Reports current target or sets a new target
|
29
|
+
login [email] [--email, --passwd] Login
|
30
|
+
info System and account information
|
31
|
+
|
32
|
+
Applications
|
33
|
+
apps List deployed applications
|
34
|
+
|
35
|
+
Application Creation
|
36
|
+
push [appname] Create, push, map, and start a new application
|
37
|
+
push [appname] --infra Push application to specified infrastructure
|
38
|
+
push [appname] --path Push application from specified path
|
39
|
+
push [appname] --url Set the url for the application
|
40
|
+
push [appname] --instances <N> Set the expected number <N> of instances
|
41
|
+
push [appname] --mem M Set the memory reservation for the application
|
42
|
+
push [appname] --runtime RUNTIME Set the runtime to use for the application
|
43
|
+
push [appname] --debug [MODE] Push application and start in a debug mode
|
44
|
+
push [appname] --no-start Do not auto-start the application
|
45
|
+
|
46
|
+
Application Operations
|
47
|
+
start <appname> [--debug [MODE]] Start the application
|
48
|
+
stop <appname> Stop the application
|
49
|
+
restart <appname> [--debug [MODE]] Restart the application
|
50
|
+
delete <appname> Delete the application
|
51
|
+
clone <src-app> <dest-app> [infra] Clone the application and services
|
52
|
+
|
53
|
+
Application Updates
|
54
|
+
update <appname> [--path,--debug [MODE]] Update the application bits
|
55
|
+
mem <appname> [memsize] Update the memory reservation for an application
|
56
|
+
map <appname> <url> Register the application to the url
|
57
|
+
unmap <appname> <url> Unregister the application from the url
|
58
|
+
instances <appname> <num|delta> Scale the application instances up or down
|
59
|
+
|
60
|
+
Application Information
|
61
|
+
crashes <appname> List recent application crashes
|
62
|
+
crashlogs <appname> Display log information for crashed applications
|
63
|
+
logs <appname> [--all] Display log information for the application
|
64
|
+
files <appname> [path] [--all] Display directory listing or file download for [path]
|
65
|
+
stats <appname> Display resource usage for the application
|
66
|
+
instances <appname> List application instances
|
67
|
+
|
68
|
+
Application Download
|
69
|
+
pull <appname> [path] Downloads last pushed source to <appname> or [path]
|
70
|
+
download <appname> [path] Downloads last pushed source to zipfile
|
71
|
+
|
72
|
+
Application Environment
|
73
|
+
env <appname> List application environment variables
|
74
|
+
env-add <appname> <variable[=]value> Add an environment variable to an application
|
75
|
+
env-del <appname> <variable> Delete an environment variable to an application
|
76
|
+
|
77
|
+
Services
|
78
|
+
services Lists of services available and provisioned
|
79
|
+
create-service <service> [--name,--bind] Create a provisioned service
|
80
|
+
create-service <service> --infra Create a provisioned service on a specified infrastructure
|
81
|
+
create-service <service> <name> Create a provisioned service and assign it <name>
|
82
|
+
create-service <service> <name> <app> Create a provisioned service and assign it <name>, and bind to <app>
|
83
|
+
delete-service [servicename] Delete a provisioned service
|
84
|
+
bind-service <servicename> <appname> Bind a service to an application
|
85
|
+
unbind-service <servicename> <appname> Unbind service from the application
|
86
|
+
clone-services <src-app> <dest-app> Clone service bindings from <src-app> application to <dest-app>
|
87
|
+
export-service <service> Export the data from a service
|
88
|
+
import-service <service> <url> Import data into a service
|
89
|
+
tunnel <servicename> [--port] Create a local tunnel to a service
|
90
|
+
tunnel <servicename> <clientcmd> Create a local tunnel to a service and start a local client
|
91
|
+
|
92
|
+
Administration
|
93
|
+
user Display user account information
|
94
|
+
passwd Change the password for the current user
|
95
|
+
logout Logs current user out of the target system
|
96
|
+
add-user [--email, --passwd] Register a new user (requires admin privileges)
|
97
|
+
delete-user <user> Delete a user and all apps and services (requires admin privileges)
|
98
|
+
|
99
|
+
System
|
100
|
+
runtimes Display the supported runtimes of the target system
|
101
|
+
frameworks Display the recognized frameworks of the target system
|
102
|
+
infras Display the available infrastructures
|
103
|
+
|
104
|
+
Micro Cloud Foundry
|
105
|
+
micro status Display Micro Cloud Foundry VM status
|
106
|
+
micro offline Configure Micro Cloud Foundry VM for offline mode
|
107
|
+
micro online Configure Micro Cloud Foundry VM for online mode
|
108
|
+
[--vmx file] Path to micro.vmx
|
109
|
+
[--vmrun executable] Path to vmrun executable
|
110
|
+
[--password cleartext] Cleartext password for guest VM vcap user
|
111
|
+
[--save] Save cleartext password in ~/.as_micro
|
112
|
+
|
113
|
+
Misc
|
114
|
+
aliases List aliases
|
115
|
+
alias <alias[=]command> Create an alias for a command
|
116
|
+
unalias <alias> Remove an alias
|
117
|
+
targets List known targets and associated authorization tokens
|
118
|
+
|
119
|
+
Help
|
120
|
+
help [command] Get general help or help on a specific command
|
121
|
+
help options Get help on available options
|
122
|
+
USAGE
|
123
|
+
|
124
|
+
end
|
125
|
+
end
|
data/lib/cli/version.rb
ADDED
data/lib/cli/zip_util.rb
ADDED
@@ -0,0 +1,77 @@
|
|
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
|
data/lib/cli.rb
ADDED
@@ -0,0 +1,48 @@
|
|
1
|
+
require "rbconfig"
|
2
|
+
|
3
|
+
ROOT = File.expand_path(File.dirname(__FILE__))
|
4
|
+
WINDOWS = !!(RbConfig::CONFIG['host_os'] =~ /mingw|mswin32|cygwin/)
|
5
|
+
|
6
|
+
module VMC
|
7
|
+
autoload :Client, "#{ROOT}/vmc/client"
|
8
|
+
autoload :Micro, "#{ROOT}/vmc/micro"
|
9
|
+
|
10
|
+
module Micro
|
11
|
+
module Switcher
|
12
|
+
autoload :Base, "#{ROOT}/vmc/micro/switcher/base"
|
13
|
+
autoload :Darwin, "#{ROOT}/vmc/micro/switcher/darwin"
|
14
|
+
autoload :Dummy, "#{ROOT}/vmc/micro/switcher/dummy"
|
15
|
+
autoload :Linux, "#{ROOT}/vmc/micro/switcher/linux"
|
16
|
+
autoload :Windows, "#{ROOT}/vmc/micro/switcher/windows"
|
17
|
+
end
|
18
|
+
autoload :VMrun, "#{ROOT}/vmc/micro/vmrun"
|
19
|
+
end
|
20
|
+
|
21
|
+
module Cli
|
22
|
+
autoload :Config, "#{ROOT}/cli/config"
|
23
|
+
autoload :Framework, "#{ROOT}/cli/frameworks"
|
24
|
+
autoload :Runner, "#{ROOT}/cli/runner"
|
25
|
+
autoload :ZipUtil, "#{ROOT}/cli/zip_util"
|
26
|
+
autoload :ServicesHelper, "#{ROOT}/cli/services_helper"
|
27
|
+
autoload :TunnelHelper, "#{ROOT}/cli/tunnel_helper"
|
28
|
+
autoload :ManifestHelper, "#{ROOT}/cli/manifest_helper"
|
29
|
+
autoload :ConsoleHelper, "#{ROOT}/cli/console_helper"
|
30
|
+
autoload :FileHelper, "#{ROOT}/cli/file_helper"
|
31
|
+
|
32
|
+
module Command
|
33
|
+
autoload :Base, "#{ROOT}/cli/commands/base"
|
34
|
+
autoload :Admin, "#{ROOT}/cli/commands/admin"
|
35
|
+
autoload :Apps, "#{ROOT}/cli/commands/apps"
|
36
|
+
autoload :Micro, "#{ROOT}/cli/commands/micro"
|
37
|
+
autoload :Misc, "#{ROOT}/cli/commands/misc"
|
38
|
+
autoload :Services, "#{ROOT}/cli/commands/services"
|
39
|
+
autoload :User, "#{ROOT}/cli/commands/user"
|
40
|
+
autoload :Manifest, "#{ROOT}/cli/commands/manifest"
|
41
|
+
end
|
42
|
+
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
require "#{ROOT}/cli/version"
|
47
|
+
require "#{ROOT}/cli/core_ext"
|
48
|
+
require "#{ROOT}/cli/errors"
|