pi 0.1.19 → 0.1.20
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/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
|