pi 0.1.19 → 0.1.20
Sign up to get free protection for your applications and to get access to all the features.
- data/README +50 -25
- data/lib/cli.rb +5 -0
- data/lib/cli/choose_helper.rb +50 -0
- data/lib/cli/commands/admin.rb +19 -0
- data/lib/cli/commands/apps.rb +566 -0
- data/lib/cli/commands/base.rb +2 -2
- data/lib/cli/commands/dns.rb +120 -0
- data/lib/cli/commands/projects.rb +85 -102
- data/lib/cli/commands/services.rb +134 -0
- data/lib/cli/commands/user.rb +14 -19
- data/lib/cli/runner.rb +112 -4
- data/lib/cli/usage.rb +24 -0
- data/lib/cli/version.rb +1 -1
- data/lib/pi/client.rb +151 -6
- data/lib/pi/const.rb +2 -0
- metadata +42 -21
data/README
CHANGED
@@ -40,6 +40,7 @@ _Copyright 2010-2012, Samsung.
|
|
40
40
|
"highline", "~> 1.6.1"
|
41
41
|
"rest-client", ">= 1.6.1", "< 1.7.0"
|
42
42
|
"terminal-table", "~> 1.4.2"
|
43
|
+
"interact", "~> 0.4.0"
|
43
44
|
|
44
45
|
2.2 Creating Your Own Gem
|
45
46
|
|
@@ -54,31 +55,55 @@ _Copyright 2010-2012, Samsung.
|
|
54
55
|
"Usage: pi [options] command [<args>] [command_options]\n" +
|
55
56
|
"Try 'pi help [command]' or 'pi help options' for more information."
|
56
57
|
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
58
|
+
Currently available pi commands are:
|
59
|
+
|
60
|
+
User
|
61
|
+
pi login [url] Login
|
62
|
+
pi logout Logs current user out of the system
|
63
|
+
pi info List system information
|
64
|
+
pi user Display user information
|
65
|
+
pi targets List available targets infomation
|
66
|
+
pi password [newpassword] Change the password for the current user
|
67
|
+
pi github [name] Bind to the github account
|
68
|
+
pi runtimes Display the supported runtimes of the system
|
69
|
+
pi frameworks Display the supported frameworks of the system
|
70
|
+
pi version Display version information
|
71
|
+
pi help [command] Get general help or help on a specific command
|
72
|
+
pi help options Get help on available options
|
73
|
+
|
74
|
+
Project
|
75
|
+
projects List created projects
|
76
|
+
create-project [projectname] Create a new project
|
77
|
+
delete-project [projectname] Delete the project
|
78
|
+
project-events [projectname] List the event info for the project
|
79
|
+
project-tags [projectname] List the tags for the project
|
80
|
+
project-commits [projectname] List the commit log for the project
|
81
|
+
project-apps [projectname] List the applications for the project
|
82
|
+
upload [projectname] Upload the war package for java project
|
72
83
|
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
84
|
+
Application
|
85
|
+
apps List deployed applications for the project
|
86
|
+
create-app [appname] Create a new application
|
87
|
+
delete-app [appid] Delete the application
|
88
|
+
start-app [appid] Start the application
|
89
|
+
stop-app [appid] Stop the application
|
90
|
+
restart-app [appid] Restart the application
|
91
|
+
scale-app [appid] Scale the application instances up or down
|
92
|
+
update-app [appid] Update the application
|
93
|
+
status [appname] Display resource usage for the application
|
94
|
+
app-env [appid] Display the environments for the application
|
95
|
+
create-env [appid] Create the environment for the application
|
96
|
+
delete-env [appid] Delete the environment for the application
|
97
|
+
app-log [appid] List the logs for the application
|
98
|
+
|
99
|
+
Service
|
100
|
+
app-service [appname] Display the bind services for the application
|
101
|
+
bind-service [appname] Bind a service to an application
|
102
|
+
unbind-service [appname] Unbind a service to an application
|
103
|
+
DNS
|
104
|
+
app-dns [appname] Display the mapped urls for the application
|
105
|
+
map-dns [appname] Map the url for the application
|
106
|
+
unmap-dns [appname] Unmap the url for the application
|
82
107
|
|
83
108
|
4. Example
|
84
109
|
|
@@ -89,7 +114,7 @@ Password: *******
|
|
89
114
|
Successfully logged into [http://api.staging.samsungcloud.org]
|
90
115
|
|
91
116
|
ubuntu@admin:~$ pi version
|
92
|
-
pi 0.1.
|
117
|
+
pi 0.1.20
|
93
118
|
|
94
119
|
ubuntu@admin:~$ pi user
|
95
120
|
|
data/lib/cli.rb
CHANGED
@@ -9,12 +9,17 @@ module PI
|
|
9
9
|
|
10
10
|
autoload :Config, "#{ROOT}/cli/config"
|
11
11
|
autoload :Runner, "#{ROOT}/cli/runner"
|
12
|
+
autoload :ChooseHelper, "#{ROOT}/cli/choose_helper"
|
12
13
|
|
13
14
|
module Command
|
14
15
|
autoload :Base, "#{ROOT}/cli/commands/base"
|
15
16
|
autoload :Projects, "#{ROOT}/cli/commands/projects"
|
16
17
|
autoload :Misc, "#{ROOT}/cli/commands/misc"
|
17
18
|
autoload :User, "#{ROOT}/cli/commands/user"
|
19
|
+
autoload :Apps, "#{ROOT}/cli/commands/apps"
|
20
|
+
autoload :Services, "#{ROOT}/cli/commands/services"
|
21
|
+
autoload :Dns, "#{ROOT}/cli/commands/dns"
|
22
|
+
autoload :Admin, "#{ROOT}/cli/commands/admin"
|
18
23
|
end
|
19
24
|
|
20
25
|
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
module PI::Cli
|
2
|
+
module ChooseHelper
|
3
|
+
|
4
|
+
def choose_project
|
5
|
+
projects = client.projects
|
6
|
+
err "No Projects" if projects.nil? || projects.empty?
|
7
|
+
useproject = nil
|
8
|
+
projects.sort! {|a, b| a[:name] <=> b[:name] }
|
9
|
+
choose do |menu|
|
10
|
+
display "=============Project Name==========="
|
11
|
+
menu.prompt = "Select Project: "
|
12
|
+
menu.select_by = :index_or_name
|
13
|
+
projects.each do |project|
|
14
|
+
menu.choice("#{project[:name]}") { useproject = project }
|
15
|
+
end
|
16
|
+
end
|
17
|
+
display "Selected Project: ",false
|
18
|
+
display "#{useproject[:name]}".green
|
19
|
+
return useproject
|
20
|
+
end
|
21
|
+
|
22
|
+
def choose_app(projectid)
|
23
|
+
apps = client.apps(projectid)
|
24
|
+
err "No Applications" if apps.nil? || apps.empty?
|
25
|
+
useapp = nil
|
26
|
+
apps.sort! {|a, b| a[:name] <=> b[:name] }
|
27
|
+
choose do |menu|
|
28
|
+
display "=============Application Name==========="
|
29
|
+
menu.prompt = "Select Application: "
|
30
|
+
menu.select_by = :index_or_name
|
31
|
+
apps.each do |app|
|
32
|
+
menu.choice("#{app[:name]}") { useapp = app }
|
33
|
+
end
|
34
|
+
end
|
35
|
+
display "Selected Application: ",false
|
36
|
+
display "#{useapp[:name]}".green
|
37
|
+
return useapp
|
38
|
+
end
|
39
|
+
|
40
|
+
def check_status(appname, eventname)
|
41
|
+
for i in 1..12 do
|
42
|
+
result = client.app_message(appname,eventname)
|
43
|
+
break result unless result[:text].empty?
|
44
|
+
sleep(10)
|
45
|
+
end
|
46
|
+
return result
|
47
|
+
end
|
48
|
+
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module PI::Cli::Command
|
2
|
+
class Admin < Base
|
3
|
+
def users
|
4
|
+
admin_domains = client.admin_domains
|
5
|
+
return display JSON.pretty_generate(admin_domains) if @options[:json]
|
6
|
+
return display "No domains!" if admin_domains.nil? || admin_domains.empty?
|
7
|
+
admin_domains.sort! {|a, b| a[:name] <=> b[:name] }
|
8
|
+
admin_domains_table = table do |t|
|
9
|
+
t.headings = 'Name', 'ID'
|
10
|
+
admin_domains.each do |s|
|
11
|
+
t << [s[:name], s[:id]]
|
12
|
+
end
|
13
|
+
end
|
14
|
+
display admin_domains_table
|
15
|
+
end
|
16
|
+
|
17
|
+
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,566 @@
|
|
1
|
+
require "rubygems"
|
2
|
+
require "interact"
|
3
|
+
require "set"
|
4
|
+
module PI::Cli::Command
|
5
|
+
class Apps < Base
|
6
|
+
include PI::Cli::ChooseHelper
|
7
|
+
include Interactive
|
8
|
+
DEFAULTS = {
|
9
|
+
"mem" => "64M",
|
10
|
+
"instances" => 1,
|
11
|
+
"needRestart" => false,
|
12
|
+
"isDebug" => false,
|
13
|
+
"needMonitor" => false
|
14
|
+
}
|
15
|
+
YES_SET = Set.new(["y", "Y", "yes", "YES"])
|
16
|
+
|
17
|
+
def apps(projectid=nil)
|
18
|
+
unless projectid
|
19
|
+
useproject = choose_project
|
20
|
+
projectid = useproject[:id]
|
21
|
+
end
|
22
|
+
app_sum = client.app_sum(projectid)
|
23
|
+
total_app = Integer(app_sum[1])
|
24
|
+
return display "No Applications" if total_app == 0
|
25
|
+
if total_app >= 50
|
26
|
+
puts "Total applications: #{total_app}."
|
27
|
+
numPerPage = nil
|
28
|
+
loop{
|
29
|
+
numPerPage = ask "Number per page"
|
30
|
+
if not numPerPage =~ /^[1-9]\d*$/
|
31
|
+
display "Invalid Number! Please input number from 1 to #{total_app}"
|
32
|
+
numPerPage =nil
|
33
|
+
next
|
34
|
+
else
|
35
|
+
break
|
36
|
+
end
|
37
|
+
}
|
38
|
+
numPerPage = numPerPage.to_i
|
39
|
+
maxpage = (total_app.to_f/numPerPage).ceil
|
40
|
+
loop{
|
41
|
+
pageNum = ask "Page number"
|
42
|
+
if not pageNum =~ /^[1-9]\d*$/
|
43
|
+
display "Invalid Number! Please input number from 1 to #{maxpage}"
|
44
|
+
pageNum =nil
|
45
|
+
next
|
46
|
+
else
|
47
|
+
break
|
48
|
+
end
|
49
|
+
}
|
50
|
+
pageNum = pageNum.to_i
|
51
|
+
else
|
52
|
+
pageNum = -1
|
53
|
+
numPerPage = -1
|
54
|
+
end
|
55
|
+
queryParam = {
|
56
|
+
:pageNum => pageNum,
|
57
|
+
:NumPerPage => numPerPage
|
58
|
+
}
|
59
|
+
apps = client.apps(projectid, queryParam)
|
60
|
+
return display JSON.pretty_generate(apps) if @options[:json]
|
61
|
+
return display "No Applications" if apps.nil? || apps.empty?
|
62
|
+
apps.sort! {|a, b| a[:name] <=> b[:name] }
|
63
|
+
apps_table = table do |t|
|
64
|
+
t.headings = 'Target', 'App name', 'URL', 'Deploy Type','Version', 'Status', 'Instances', 'Running Instances'
|
65
|
+
apps.each do |app|
|
66
|
+
t << [app[:targetName], app[:name] ,app[:url], app[:deployType], app[:tag], app[:status], app[:instances], app[:runInstances]]
|
67
|
+
end
|
68
|
+
end
|
69
|
+
display apps_table
|
70
|
+
end
|
71
|
+
|
72
|
+
def create_app(appname=nil)
|
73
|
+
projectid, mem, tag, binarylist, branch, deployType, instances = nil, nil, nil, nil, nil, nil, nil
|
74
|
+
loop{
|
75
|
+
appname = ask "Application Name" unless appname
|
76
|
+
if app_exists_byappname?(appname)
|
77
|
+
display "Application '#{appname}' already exists."
|
78
|
+
appname =nil
|
79
|
+
next
|
80
|
+
else
|
81
|
+
break
|
82
|
+
end
|
83
|
+
}
|
84
|
+
|
85
|
+
# choose the project
|
86
|
+
useproject = choose_project
|
87
|
+
projectid = useproject[:id]
|
88
|
+
|
89
|
+
# choose the tag
|
90
|
+
if useproject[:runtime] =~ /^(ruby)/i
|
91
|
+
tag = client.project_tags(useproject[:name])
|
92
|
+
err "No tags!" if tag.nil? || tag.empty?
|
93
|
+
if tag.count == 1
|
94
|
+
tag = tag[0]
|
95
|
+
display "Tag: #{tag}"
|
96
|
+
deployType = "git"
|
97
|
+
else
|
98
|
+
choose do |menu|
|
99
|
+
display "=============Tags==============="
|
100
|
+
menu.prompt = "Select Tag: "
|
101
|
+
menu.select_by = :index_or_name
|
102
|
+
tag.each do |t|
|
103
|
+
menu.choice(t) { tag = t }
|
104
|
+
end
|
105
|
+
end
|
106
|
+
display "Selected Version: ",false
|
107
|
+
display "#{tag}"
|
108
|
+
deployType = "git"
|
109
|
+
end
|
110
|
+
else
|
111
|
+
binarylist = client.project_binary(projectid)
|
112
|
+
err "No version!" if binarylist.nil? || binarylist.empty?
|
113
|
+
choose do |menu|
|
114
|
+
display "=============Versions============"
|
115
|
+
menu.prompt = "Select Version: "
|
116
|
+
menu.select_by = :index_or_name
|
117
|
+
binarylist.each do |version|
|
118
|
+
menu.choice("#{version[:versionName]}") { tag = version }
|
119
|
+
end
|
120
|
+
end
|
121
|
+
display "Selected Version: ",false
|
122
|
+
display "#{tag[:versionName]}"
|
123
|
+
tag = tag[:versionName]
|
124
|
+
deployType = "binary"
|
125
|
+
end
|
126
|
+
|
127
|
+
# choose the target
|
128
|
+
targets = client.targets
|
129
|
+
err "No Targets!" if targets.nil? || targets.empty?
|
130
|
+
usetarget = nil
|
131
|
+
choose do |menu|
|
132
|
+
display "=============Targets============"
|
133
|
+
menu.prompt = "Select Target: "
|
134
|
+
menu.select_by = :index_or_name
|
135
|
+
targets.each do |target|
|
136
|
+
menu.choice("#{target[:name]}-#{target[:targetUrl]}") { usetarget = target }
|
137
|
+
end
|
138
|
+
end
|
139
|
+
display "Selected Target: ",false
|
140
|
+
display "#{usetarget[:name]}-#{usetarget[:targetUrl]}"
|
141
|
+
target_memory = client.target_memory(usetarget[:name])
|
142
|
+
target_memory = target_memory[1]
|
143
|
+
display ("Available memory: #{target_memory} M")
|
144
|
+
# URL combination
|
145
|
+
user = client.user_info
|
146
|
+
url = "#{appname}.#{user[:userName]}.#{usetarget[:name]}.samsungpaas.com"
|
147
|
+
display "URL: #{url}"
|
148
|
+
# choose the mem
|
149
|
+
mem = ask "Memory reservation", :default => DEFAULTS["mem"], :choices => ["64M", "128M", "256M", "512M", "1G", "2G"]
|
150
|
+
# Set to MB number
|
151
|
+
mem_quota = mem_choice_to_quota(mem)
|
152
|
+
|
153
|
+
loop{
|
154
|
+
instances = ask "How many instances?", :default => DEFAULTS["instances"]
|
155
|
+
instances = instances.to_s
|
156
|
+
if not instances =~ /^[1-9]\d*$/
|
157
|
+
display "Invalid Number!"
|
158
|
+
instances =nil
|
159
|
+
next
|
160
|
+
else
|
161
|
+
break
|
162
|
+
end
|
163
|
+
}
|
164
|
+
|
165
|
+
isDebug = ask "Need debug?", :default => DEFAULTS["isDebug"] if deployType == "binary"
|
166
|
+
needRestart = ask "Need restart?", :default => DEFAULTS["needRestart"]
|
167
|
+
needMonitor = ask "Need monitor?", :default => DEFAULTS["needMonitor"]
|
168
|
+
if not isDebug.nil?
|
169
|
+
isDebug = (isDebug == false ? "no" : "yes")
|
170
|
+
else
|
171
|
+
isDebug = "no"
|
172
|
+
end
|
173
|
+
if not needRestart.nil?
|
174
|
+
needRestart = (needRestart == false ? "no" : "yes")
|
175
|
+
else
|
176
|
+
needRestart = "no"
|
177
|
+
end
|
178
|
+
if not needMonitor.nil?
|
179
|
+
needMonitor = (needMonitor == false ? "no" : "yes")
|
180
|
+
else
|
181
|
+
needMonitor = "no"
|
182
|
+
end
|
183
|
+
# choose the branch
|
184
|
+
branch = client.project_branchs(useproject[:name])
|
185
|
+
err "No branchs!" if branch.nil? || branch.empty?
|
186
|
+
if branch.count == 1
|
187
|
+
branch = branch[0]
|
188
|
+
display "Branch: #{branch}"
|
189
|
+
else
|
190
|
+
choose do |menu|
|
191
|
+
display "=============Branchs============"
|
192
|
+
menu.prompt = "Select Branch: "
|
193
|
+
menu.default = "master"
|
194
|
+
menu.select_by = :index_or_name
|
195
|
+
branch.each do |b|
|
196
|
+
menu.choice(b) { branch = b }
|
197
|
+
end
|
198
|
+
end
|
199
|
+
display "Selected Branch: ",false
|
200
|
+
display "#{branch}"
|
201
|
+
end
|
202
|
+
|
203
|
+
manifest = {
|
204
|
+
:name => "#{appname}",
|
205
|
+
:targetName => "#{usetarget[:name]}",
|
206
|
+
:branch => branch,
|
207
|
+
:url => url,
|
208
|
+
:memory => mem_quota,
|
209
|
+
:instances => instances,
|
210
|
+
:deployType => deployType,
|
211
|
+
:tag => tag,
|
212
|
+
:isDebug => isDebug,
|
213
|
+
:needRestart => needRestart,
|
214
|
+
:needMonitor => needMonitor
|
215
|
+
}
|
216
|
+
|
217
|
+
display "Creating application \"#{appname}\": ",false
|
218
|
+
|
219
|
+
t = Thread.new do
|
220
|
+
loop do
|
221
|
+
display '.', false
|
222
|
+
sleep (1)
|
223
|
+
break unless t.alive?
|
224
|
+
end
|
225
|
+
end
|
226
|
+
|
227
|
+
client.create_app(projectid, manifest)
|
228
|
+
result = check_status(appname, "create")
|
229
|
+
Thread.kill(t)
|
230
|
+
if result[:code] == 200
|
231
|
+
if not result[:text].empty?
|
232
|
+
display "OK".green
|
233
|
+
else
|
234
|
+
display "Please try again"
|
235
|
+
end
|
236
|
+
else
|
237
|
+
err result[:text]
|
238
|
+
end
|
239
|
+
end
|
240
|
+
|
241
|
+
def delete_app(appid=nil)
|
242
|
+
unless appid
|
243
|
+
useproject = choose_project
|
244
|
+
projectid = useproject[:id]
|
245
|
+
useapp = choose_app(projectid)
|
246
|
+
appid = useapp[:id]
|
247
|
+
end
|
248
|
+
err "The application is not found! App id :#{appid}" unless app_exists_byappid?(appid)
|
249
|
+
display "Deleting application: ",false
|
250
|
+
|
251
|
+
t = Thread.new do
|
252
|
+
loop do
|
253
|
+
display '.', false
|
254
|
+
sleep (1)
|
255
|
+
break unless t.alive?
|
256
|
+
end
|
257
|
+
end
|
258
|
+
|
259
|
+
client.delete_app(appid)
|
260
|
+
Thread.kill(t)
|
261
|
+
display "OK".green
|
262
|
+
end
|
263
|
+
|
264
|
+
def start_app(appid=nil)
|
265
|
+
unless appid
|
266
|
+
useproject = choose_project
|
267
|
+
projectid = useproject[:id]
|
268
|
+
useapp = choose_app(projectid)
|
269
|
+
appid = useapp[:id]
|
270
|
+
end
|
271
|
+
app = client.app_get_byid(appid)
|
272
|
+
err "The application is not found! App id :#{appid}" unless (appid.to_f == app[:id] ? true : false)
|
273
|
+
display "Starting application: ",false
|
274
|
+
|
275
|
+
t = Thread.new do
|
276
|
+
loop do
|
277
|
+
display '.', false
|
278
|
+
sleep (1)
|
279
|
+
break unless t.alive?
|
280
|
+
end
|
281
|
+
end
|
282
|
+
|
283
|
+
client.start_app(appid)
|
284
|
+
result = check_status(app[:name], "start")
|
285
|
+
Thread.kill(t)
|
286
|
+
if result[:code] == 200
|
287
|
+
display "OK".green
|
288
|
+
else
|
289
|
+
err result[:text]
|
290
|
+
end
|
291
|
+
end
|
292
|
+
|
293
|
+
def stop_app(appid=nil)
|
294
|
+
unless appid
|
295
|
+
useproject = choose_project
|
296
|
+
projectid = useproject[:id]
|
297
|
+
useapp = choose_app(projectid)
|
298
|
+
appid = useapp[:id]
|
299
|
+
end
|
300
|
+
err "The application is not found! App id :#{appid}" unless app_exists_byappid?(appid)
|
301
|
+
display "Stoping application: ",false
|
302
|
+
client.stop_app(appid)
|
303
|
+
display "OK".green
|
304
|
+
end
|
305
|
+
|
306
|
+
def restart_app(appid=nil)
|
307
|
+
unless appid
|
308
|
+
useproject = choose_project
|
309
|
+
projectid = useproject[:id]
|
310
|
+
useapp = choose_app(projectid)
|
311
|
+
appid = useapp[:id]
|
312
|
+
end
|
313
|
+
app = client.app_get_byid(appid)
|
314
|
+
err "The application is not found! App id :#{appid}" unless (appid.to_f == app[:id] ? true : false)
|
315
|
+
stop_app(appid)
|
316
|
+
start_app(appid)
|
317
|
+
end
|
318
|
+
|
319
|
+
def scale_app(appid=nil)
|
320
|
+
unless appid
|
321
|
+
useproject = choose_project
|
322
|
+
projectid = useproject[:id]
|
323
|
+
useapp = choose_app(projectid)
|
324
|
+
appid = useapp[:id]
|
325
|
+
end
|
326
|
+
app = client.app_get_byid(appid)
|
327
|
+
err "The application is not found! App id :#{appid}" unless (appid.to_f == app[:id] ? true : false)
|
328
|
+
instance = nil
|
329
|
+
loop{
|
330
|
+
instance = ask "How many instances?", :default => app[:instances]
|
331
|
+
instance = instance.to_s
|
332
|
+
if not instance =~ /^[1-9]\d*$/
|
333
|
+
display "Invalid Number!"
|
334
|
+
instance =nil
|
335
|
+
next
|
336
|
+
else
|
337
|
+
break
|
338
|
+
end
|
339
|
+
}
|
340
|
+
display "Scaling application: ",false
|
341
|
+
|
342
|
+
t = Thread.new do
|
343
|
+
loop do
|
344
|
+
display '.', false
|
345
|
+
sleep (1)
|
346
|
+
break unless t.alive?
|
347
|
+
end
|
348
|
+
end
|
349
|
+
|
350
|
+
client.scale_app(appid,instance)
|
351
|
+
result = check_status(app[:name], "scale")
|
352
|
+
Thread.kill(t)
|
353
|
+
if result[:code] == 200
|
354
|
+
display "OK".green
|
355
|
+
else
|
356
|
+
err result[:text]
|
357
|
+
end
|
358
|
+
end
|
359
|
+
|
360
|
+
def update_app(appid=nil)
|
361
|
+
unless appid
|
362
|
+
useproject = choose_project
|
363
|
+
projectid = useproject[:id]
|
364
|
+
projectname = useproject[:name]
|
365
|
+
useapp = choose_app(projectid)
|
366
|
+
appid = useapp[:id]
|
367
|
+
end
|
368
|
+
app = client.app_get_byid(appid)
|
369
|
+
err "The application is not found! App id :#{appid}" unless (appid.to_f == app[:id] ? true : false)
|
370
|
+
if app[:deployType] == "git"
|
371
|
+
unless useproject
|
372
|
+
projects = client.projects
|
373
|
+
projects.each do |p|
|
374
|
+
projectname = p[:name] if p[:id] == app[:projectId]
|
375
|
+
end
|
376
|
+
end
|
377
|
+
tag = client.project_tags(projectname)
|
378
|
+
err "No tags!" if tag.nil? || tag.empty?
|
379
|
+
choose do |menu|
|
380
|
+
display "=============Tags==============="
|
381
|
+
menu.prompt = "Select Tag: "
|
382
|
+
menu.select_by = :index_or_name
|
383
|
+
tag.each do |t|
|
384
|
+
menu.choice(t) { tag = t }
|
385
|
+
end
|
386
|
+
end
|
387
|
+
display "Selected tag: ",false
|
388
|
+
display "#{tag}"
|
389
|
+
else
|
390
|
+
tag = client.project_binary(app[:projectId])
|
391
|
+
puts tag
|
392
|
+
puts tag.class
|
393
|
+
err "No version!" if tag.nil? || tag.empty?
|
394
|
+
choose do |menu|
|
395
|
+
display "=============Versions============"
|
396
|
+
menu.prompt = "Select Version: "
|
397
|
+
menu.select_by = :index_or_name
|
398
|
+
tag.each do |version|
|
399
|
+
menu.choice("#{version[:versionName]}") { tag = version[:versionName] }
|
400
|
+
end
|
401
|
+
end
|
402
|
+
display "Selected Version: ",false
|
403
|
+
display "#{tag}"
|
404
|
+
end
|
405
|
+
display "Updating application: ",false
|
406
|
+
|
407
|
+
t = Thread.new do
|
408
|
+
loop do
|
409
|
+
display '.', false
|
410
|
+
sleep (1)
|
411
|
+
break unless t.alive?
|
412
|
+
end
|
413
|
+
end
|
414
|
+
|
415
|
+
client.update_app(appid,tag)
|
416
|
+
result = check_status(app[:name], "rollback")
|
417
|
+
Thread.kill(t)
|
418
|
+
if result[:code] == 200
|
419
|
+
display "OK".green
|
420
|
+
else
|
421
|
+
err result[:text]
|
422
|
+
end
|
423
|
+
end
|
424
|
+
|
425
|
+
def status(appname=nil)
|
426
|
+
unless appname
|
427
|
+
useproject = choose_project
|
428
|
+
projectid = useproject[:id]
|
429
|
+
useapp = choose_app(projectid)
|
430
|
+
appname = useapp[:name]
|
431
|
+
end
|
432
|
+
app = client.app_get_byname(appname)
|
433
|
+
err "The application is not found! App name :#{appname}" unless (appname == app[:name] ? true : false )
|
434
|
+
status = client.status(appname)
|
435
|
+
return display JSON.pretty_generate(status) if @options[:json]
|
436
|
+
return display "No Status!" if status.nil? || status.empty?
|
437
|
+
status_table = table do |t|
|
438
|
+
t.headings = 'Instance ID', 'CPU', 'Memory', 'Disk', 'RequestCount', 'ErrorCount'
|
439
|
+
status.each do |s|
|
440
|
+
t << [s[:instancesId], s[:cpu], s[:memory], s[:disk], s[:requestCount], s[:errorCount]]
|
441
|
+
end
|
442
|
+
end
|
443
|
+
display status_table
|
444
|
+
end
|
445
|
+
|
446
|
+
def app_env(appname=nil)
|
447
|
+
unless appname
|
448
|
+
useproject = choose_project
|
449
|
+
projectid = useproject[:id]
|
450
|
+
useapp = choose_app(projectid)
|
451
|
+
appname = useapp[:name]
|
452
|
+
end
|
453
|
+
app = client.app_get_byname(appname)
|
454
|
+
err "The application is not found! App name :#{appname}" unless (appname == app[:name] ? true : false)
|
455
|
+
env = client.app_env(appname)
|
456
|
+
return display JSON.pretty_generate(env) if @options[:json]
|
457
|
+
return display "No Environments!" if env.nil? || env.empty?
|
458
|
+
env.sort! {|a, b| a[:name] <=> b[:name] }
|
459
|
+
env_table = table do |t|
|
460
|
+
t.headings = 'Name', 'Value'
|
461
|
+
env.each do |e|
|
462
|
+
t << [e[:name], e[:value]]
|
463
|
+
end
|
464
|
+
end
|
465
|
+
display env_table
|
466
|
+
end
|
467
|
+
|
468
|
+
def create_env(appname=nil)
|
469
|
+
unless appname
|
470
|
+
useproject = choose_project
|
471
|
+
projectid = useproject[:id]
|
472
|
+
useapp = choose_app(projectid)
|
473
|
+
appname = useapp[:name]
|
474
|
+
end
|
475
|
+
app = client.app_get_byname(appname)
|
476
|
+
err "The application is not found! App name :#{appname}" unless (appname == app[:name] ? true : false)
|
477
|
+
name = nil
|
478
|
+
loop{
|
479
|
+
name = ask "Environment Name" unless name
|
480
|
+
if env_exists_byappname?(app[:name],name)
|
481
|
+
display "Environment '#{name}' already exists."
|
482
|
+
name =nil
|
483
|
+
next
|
484
|
+
else
|
485
|
+
break
|
486
|
+
end
|
487
|
+
}
|
488
|
+
value = ask "Environment Value"
|
489
|
+
manifest = {
|
490
|
+
:name => name,
|
491
|
+
:value => value
|
492
|
+
}
|
493
|
+
client.create_env(appname, manifest)
|
494
|
+
display "OK".green
|
495
|
+
end
|
496
|
+
|
497
|
+
def delete_env(appname=nil)
|
498
|
+
unless appname
|
499
|
+
useproject = choose_project
|
500
|
+
projectid = useproject[:id]
|
501
|
+
useapp = choose_app(projectid)
|
502
|
+
appname = useapp[:name]
|
503
|
+
end
|
504
|
+
app = client.app_get_byname(appname)
|
505
|
+
err "The application is not found! App name :#{appname}" unless (appname == app[:name] ? true : false)
|
506
|
+
name = ask "Environment Name"
|
507
|
+
err "No Environment '#{name}'!" unless env_exists_byappname?(app[:name],name)
|
508
|
+
value = nil
|
509
|
+
env = client.app_env(app[:name])
|
510
|
+
env.each do |e|
|
511
|
+
value = e[:value] if name == e[:name]
|
512
|
+
end
|
513
|
+
manifest = "#{name}=#{value}".to_a
|
514
|
+
client.delete_env(appname,manifest)
|
515
|
+
display "OK".green
|
516
|
+
end
|
517
|
+
|
518
|
+
def app_log(appid=nil)
|
519
|
+
unless appid
|
520
|
+
useproject = choose_project
|
521
|
+
projectid = useproject[:id]
|
522
|
+
useapp = choose_app(projectid)
|
523
|
+
appid = useapp[:id]
|
524
|
+
end
|
525
|
+
app = client.app_get_byid(appid)
|
526
|
+
err "The application is not found! App id :#{appid}" unless (appid.to_f == app[:id] ? true : false)
|
527
|
+
max_index = app[:instances]-1
|
528
|
+
instanceindex = ask "Select instance index(from 0 to #{max_index})", :default => 0
|
529
|
+
filepath = "logs/"
|
530
|
+
logs = client.app_log(app[:id],filepath,instanceindex)
|
531
|
+
logs = logs[1].to_a
|
532
|
+
file = ask "Select logs, indexed list?", :choices => logs, :indexed => true
|
533
|
+
display "Selected logs: ",false
|
534
|
+
file = file.split(' ')
|
535
|
+
file = file[0]
|
536
|
+
display "#{file}"
|
537
|
+
filepath = "logs/#{file}"
|
538
|
+
logs = client.app_log(app[:id],filepath,instanceindex)
|
539
|
+
display "\n"
|
540
|
+
display logs[1]
|
541
|
+
end
|
542
|
+
|
543
|
+
private
|
544
|
+
|
545
|
+
def app_exists_byappname?(appname=nil)
|
546
|
+
app = client.app_get_byname(appname)
|
547
|
+
appname == app[:name] ? true : false
|
548
|
+
end
|
549
|
+
|
550
|
+
def app_exists_byappid?(appid=nil)
|
551
|
+
app = client.app_get_byid(appid)
|
552
|
+
appid.to_f == app[:id] ? true : false
|
553
|
+
end
|
554
|
+
|
555
|
+
def env_exists_byappname?(appname,name)
|
556
|
+
env = client.env_verify(appname,name)
|
557
|
+
"true" == env[1] ? false : true
|
558
|
+
end
|
559
|
+
|
560
|
+
def mem_choice_to_quota(mem_choice)
|
561
|
+
(mem_choice =~ /(\d+)M/i) ? mem_quota = $1.to_i : mem_quota = mem_choice.to_i * 1024
|
562
|
+
mem_quota
|
563
|
+
end
|
564
|
+
|
565
|
+
end
|
566
|
+
end
|