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