opennebula-cli 5.12.8 → 5.13.80.pre
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.
- checksums.yaml +4 -4
- data/bin/oneacct +9 -4
- data/bin/oneacl +8 -5
- data/bin/onecluster +10 -7
- data/bin/onedatastore +10 -7
- data/bin/oneflow +85 -13
- data/bin/oneflow-template +45 -8
- data/bin/onegroup +10 -7
- data/bin/onehook +10 -7
- data/bin/onehost +8 -5
- data/bin/oneimage +99 -8
- data/bin/onemarket +10 -7
- data/bin/onemarketapp +117 -10
- data/bin/onesecgroup +13 -7
- data/bin/oneshowback +18 -10
- data/bin/onetemplate +12 -8
- data/bin/oneuser +30 -7
- data/bin/onevcenter +7 -4
- data/bin/onevdc +10 -7
- data/bin/onevm +146 -11
- data/bin/onevmgroup +13 -7
- data/bin/onevnet +8 -5
- data/bin/onevntemplate +11 -7
- data/bin/onevrouter +10 -7
- data/bin/onezone +10 -7
- data/lib/cli_helper.rb +4 -6
- data/lib/command_parser.rb +1 -1
- data/lib/one_helper.rb +398 -37
- data/lib/one_helper/oneacct_helper.rb +8 -17
- data/lib/one_helper/oneacl_helper.rb +1 -1
- data/lib/one_helper/onecluster_helper.rb +1 -1
- data/lib/one_helper/onedatastore_helper.rb +11 -1
- data/lib/one_helper/oneflow_helper.rb +20 -5
- data/lib/one_helper/oneflowtemplate_helper.rb +28 -2
- data/lib/one_helper/onegroup_helper.rb +1 -1
- data/lib/one_helper/onehook_helper.rb +1 -1
- data/lib/one_helper/onehost_helper.rb +1 -5
- data/lib/one_helper/oneimage_helper.rb +7 -7
- data/lib/one_helper/onemarket_helper.rb +1 -1
- data/lib/one_helper/onemarketapp_helper.rb +494 -96
- data/lib/one_helper/onequota_helper.rb +1 -1
- data/lib/one_helper/onesecgroup_helper.rb +1 -1
- data/lib/one_helper/onetemplate_helper.rb +12 -1
- data/lib/one_helper/oneuser_helper.rb +11 -3
- data/lib/one_helper/onevcenter_helper.rb +176 -146
- data/lib/one_helper/onevdc_helper.rb +1 -1
- data/lib/one_helper/onevm_helper.rb +4 -3
- data/lib/one_helper/onevmgroup_helper.rb +1 -1
- data/lib/one_helper/onevnet_helper.rb +1 -1
- data/lib/one_helper/onevntemplate_helper.rb +1 -1
- data/lib/one_helper/onevrouter_helper.rb +1 -20
- data/lib/one_helper/onezone_helper.rb +12 -1
- data/share/schemas/xsd/acct.xsd +179 -0
- data/share/schemas/xsd/acl_pool.xsd +22 -0
- data/share/schemas/xsd/api_info.xsd +43 -0
- data/share/schemas/xsd/cluster.xsd +34 -0
- data/share/schemas/xsd/cluster_pool.xsd +12 -0
- data/share/schemas/xsd/datastore.xsd +67 -0
- data/share/schemas/xsd/datastore_pool.xsd +12 -0
- data/share/schemas/xsd/document.xsd +42 -0
- data/share/schemas/xsd/document_pool.xsd +12 -0
- data/share/schemas/xsd/group.xsd +179 -0
- data/share/schemas/xsd/group_pool.xsd +194 -0
- data/share/schemas/xsd/hook.xsd +59 -0
- data/share/schemas/xsd/hook_message_api.xsd +14 -0
- data/share/schemas/xsd/hook_message_retry.xsd +12 -0
- data/share/schemas/xsd/hook_message_state.xsd +25 -0
- data/share/schemas/xsd/hook_pool.xsd +12 -0
- data/share/schemas/xsd/host.xsd +164 -0
- data/share/schemas/xsd/host_pool.xsd +12 -0
- data/share/schemas/xsd/image.xsd +123 -0
- data/share/schemas/xsd/image_pool.xsd +12 -0
- data/share/schemas/xsd/index.xsd +49 -0
- data/share/schemas/xsd/marketplace.xsd +44 -0
- data/share/schemas/xsd/marketplace_pool.xsd +12 -0
- data/share/schemas/xsd/marketplaceapp.xsd +56 -0
- data/share/schemas/xsd/marketplaceapp_pool.xsd +12 -0
- data/share/schemas/xsd/opennebula_configuration.xsd +412 -0
- data/share/schemas/xsd/raftstatus.xsd +18 -0
- data/share/schemas/xsd/security_group.xsd +74 -0
- data/share/schemas/xsd/security_group_pool.xsd +12 -0
- data/share/schemas/xsd/showback.xsd +29 -0
- data/share/schemas/xsd/user.xsd +186 -0
- data/share/schemas/xsd/user_pool.xsd +201 -0
- data/share/schemas/xsd/vdc.xsd +76 -0
- data/share/schemas/xsd/vdc_pool.xsd +12 -0
- data/share/schemas/xsd/vm.xsd +251 -0
- data/share/schemas/xsd/vm_group.xsd +59 -0
- data/share/schemas/xsd/vm_group_pool.xsd +12 -0
- data/share/schemas/xsd/vm_pool.xsd +114 -0
- data/share/schemas/xsd/vmtemplate.xsd +52 -0
- data/share/schemas/xsd/vmtemplate_pool.xsd +12 -0
- data/share/schemas/xsd/vnet.xsd +137 -0
- data/share/schemas/xsd/vnet_pool.xsd +85 -0
- data/share/schemas/xsd/vntemplate.xsd +50 -0
- data/share/schemas/xsd/vntemplate_pool.xsd +12 -0
- data/share/schemas/xsd/vrouter.xsd +49 -0
- data/share/schemas/xsd/vrouter_pool.xsd +12 -0
- data/share/schemas/xsd/zone.xsd +40 -0
- data/share/schemas/xsd/zone_pool.xsd +36 -0
- metadata +68 -7
- data/lib/one_helper/oneprovision_helper.rb +0 -362
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
# -------------------------------------------------------------------------- #
|
|
2
|
-
# Copyright 2002-
|
|
2
|
+
# Copyright 2002-2021, OpenNebula Project, OpenNebula Systems #
|
|
3
3
|
# #
|
|
4
4
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may #
|
|
5
5
|
# not use this file except in compliance with the License. You may obtain #
|
|
@@ -91,28 +91,19 @@ class AcctHelper < OpenNebulaHelper::OneHelper
|
|
|
91
91
|
:format => String
|
|
92
92
|
}
|
|
93
93
|
|
|
94
|
-
XML = {
|
|
95
|
-
:name => "xml",
|
|
96
|
-
:short => "-x",
|
|
97
|
-
:large => "--xml",
|
|
98
|
-
:description => "Show the resource in xml format"
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
JSON = {
|
|
102
|
-
:name => "json",
|
|
103
|
-
:short => "-j",
|
|
104
|
-
:large => "--json",
|
|
105
|
-
:description => "Show the resource in json format"
|
|
106
|
-
}
|
|
107
|
-
|
|
108
94
|
SPLIT={
|
|
109
95
|
:name => "split",
|
|
110
96
|
:large => "--split",
|
|
111
97
|
:description => "Split the output in a table for each VM"
|
|
112
98
|
}
|
|
113
99
|
|
|
114
|
-
ACCT_OPTIONS = [START_TIME_ACCT, END_TIME_ACCT, USERFILTER, GROUP, HOST, XPATH,
|
|
115
|
-
SHOWBACK_OPTIONS = [START_TIME_SHOWBACK, END_TIME_SHOWBACK, USERFILTER, GROUP
|
|
100
|
+
ACCT_OPTIONS = [START_TIME_ACCT, END_TIME_ACCT, USERFILTER, GROUP, HOST, XPATH, SPLIT]
|
|
101
|
+
SHOWBACK_OPTIONS = [START_TIME_SHOWBACK, END_TIME_SHOWBACK, USERFILTER, GROUP]
|
|
102
|
+
|
|
103
|
+
ACCT_OPTIONS << OpenNebulaHelper::XML
|
|
104
|
+
ACCT_OPTIONS << OpenNebulaHelper::JSON
|
|
105
|
+
|
|
106
|
+
SHOWBACK_OPTIONS += OpenNebulaHelper::FORMAT
|
|
116
107
|
|
|
117
108
|
ACCT_TABLE = CLIHelper::ShowTable.new(self.table_conf("oneacct.yaml"), nil) do
|
|
118
109
|
column :UID, "User ID", :size=>4 do |d|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
# -------------------------------------------------------------------------- #
|
|
2
|
-
# Copyright 2002-
|
|
2
|
+
# Copyright 2002-2021, OpenNebula Project, OpenNebula Systems #
|
|
3
3
|
# #
|
|
4
4
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may #
|
|
5
5
|
# not use this file except in compliance with the License. You may obtain #
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
# -------------------------------------------------------------------------- #
|
|
2
|
-
# Copyright 2002-
|
|
2
|
+
# Copyright 2002-2021, OpenNebula Project, OpenNebula Systems #
|
|
3
3
|
# #
|
|
4
4
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may #
|
|
5
5
|
# not use this file except in compliance with the License. You may obtain #
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
# -------------------------------------------------------------------------- #
|
|
2
|
-
# Copyright 2002-
|
|
2
|
+
# Copyright 2002-2021, OpenNebula Project, OpenNebula Systems #
|
|
3
3
|
# #
|
|
4
4
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may #
|
|
5
5
|
# not use this file except in compliance with the License. You may obtain #
|
|
@@ -28,6 +28,16 @@ class OneDatastoreHelper < OpenNebulaHelper::OneHelper
|
|
|
28
28
|
}
|
|
29
29
|
}
|
|
30
30
|
|
|
31
|
+
FILE_DATASTORE = {
|
|
32
|
+
:name => "file_datastore",
|
|
33
|
+
:large => "--file-datastore id|name" ,
|
|
34
|
+
:description => "Selects the file datastore",
|
|
35
|
+
:format => String,
|
|
36
|
+
:proc => lambda { |o, options|
|
|
37
|
+
OpenNebulaHelper.rname_to_id(o, "DATASTORE")
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
31
41
|
def self.rname
|
|
32
42
|
"DATASTORE"
|
|
33
43
|
end
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
# -------------------------------------------------------------------------- #
|
|
2
|
-
# Copyright 2002-
|
|
2
|
+
# Copyright 2002-2021, OpenNebula Project, OpenNebula Systems #
|
|
3
3
|
# #
|
|
4
4
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may #
|
|
5
5
|
# not use this file except in compliance with the License. You may obtain #
|
|
@@ -57,11 +57,18 @@ class OneFlowHelper < OpenNebulaHelper::OneHelper
|
|
|
57
57
|
d['NAME']
|
|
58
58
|
end
|
|
59
59
|
|
|
60
|
+
column :STARTTIME, 'Start time of the Service', :size => 15 do |d|
|
|
61
|
+
d.extend(CLIHelper::HashWithSearch)
|
|
62
|
+
d = d.dsearch('TEMPLATE/BODY')
|
|
63
|
+
|
|
64
|
+
OpenNebulaHelper.time_to_str(d['start_time'])
|
|
65
|
+
end
|
|
66
|
+
|
|
60
67
|
column :STAT, 'State', :size => 11, :left => true do |d|
|
|
61
68
|
Service.state_str(d['TEMPLATE']['BODY']['state'])
|
|
62
69
|
end
|
|
63
70
|
|
|
64
|
-
default :ID, :USER, :GROUP, :NAME, :STAT
|
|
71
|
+
default :ID, :USER, :GROUP, :NAME, :STARTTIME, :STAT
|
|
65
72
|
end
|
|
66
73
|
end
|
|
67
74
|
|
|
@@ -74,6 +81,8 @@ class OneFlowHelper < OpenNebulaHelper::OneHelper
|
|
|
74
81
|
|
|
75
82
|
if CloudClient.is_error?(response)
|
|
76
83
|
[response.code.to_i, response.to_s]
|
|
84
|
+
elsif options[:yaml]
|
|
85
|
+
[0, JSON.parse(response.body).to_yaml(:indent => 4)]
|
|
77
86
|
else
|
|
78
87
|
array_list = JSON.parse(response.body)
|
|
79
88
|
array_list = array_list['DOCUMENT_POOL']['DOCUMENT']
|
|
@@ -93,6 +102,8 @@ class OneFlowHelper < OpenNebulaHelper::OneHelper
|
|
|
93
102
|
else
|
|
94
103
|
[0, JSON.pretty_generate(array_list)]
|
|
95
104
|
end
|
|
105
|
+
elsif options[:yaml]
|
|
106
|
+
[0, array_list.to_yaml(:indent => 4)]
|
|
96
107
|
else
|
|
97
108
|
format_service_pool.show(array_list)
|
|
98
109
|
|
|
@@ -139,6 +150,8 @@ class OneFlowHelper < OpenNebulaHelper::OneHelper
|
|
|
139
150
|
else
|
|
140
151
|
if options[:json]
|
|
141
152
|
[0, response.body]
|
|
153
|
+
elsif options[:yaml]
|
|
154
|
+
[0, JSON.parse(response.body).to_yaml(:indent => 4)]
|
|
142
155
|
else
|
|
143
156
|
str_h1 = '%-80s'
|
|
144
157
|
document = JSON.parse(response.body)['DOCUMENT']
|
|
@@ -260,9 +273,10 @@ class OneFlowHelper < OpenNebulaHelper::OneHelper
|
|
|
260
273
|
#
|
|
261
274
|
# @param document [Hash] Service document information
|
|
262
275
|
def print_service_info(document)
|
|
263
|
-
str
|
|
264
|
-
str_h1
|
|
265
|
-
template
|
|
276
|
+
str = '%-20s: %-20s'
|
|
277
|
+
str_h1 = '%-80s'
|
|
278
|
+
template = document['TEMPLATE']['BODY']
|
|
279
|
+
start_time = OpenNebulaHelper.time_to_str(template['start_time'])
|
|
266
280
|
|
|
267
281
|
puts Kernel.format(str, 'ID', document['ID'])
|
|
268
282
|
puts Kernel.format(str, 'NAME', document['NAME'])
|
|
@@ -273,6 +287,7 @@ class OneFlowHelper < OpenNebulaHelper::OneHelper
|
|
|
273
287
|
puts Kernel.format(str,
|
|
274
288
|
'SERVICE STATE',
|
|
275
289
|
Service.state_str(template['state']))
|
|
290
|
+
puts Kernel.format(str, 'START TIME', start_time)
|
|
276
291
|
|
|
277
292
|
if template['shutdown_action']
|
|
278
293
|
puts Kernel.format(str, 'SHUTDOWN', template['shutdown_action'])
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
# -------------------------------------------------------------------------- #
|
|
2
|
-
# Copyright 2002-
|
|
2
|
+
# Copyright 2002-2021, OpenNebula Project, OpenNebula Systems #
|
|
3
3
|
# #
|
|
4
4
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may #
|
|
5
5
|
# not use this file except in compliance with the License. You may obtain #
|
|
@@ -57,7 +57,16 @@ class OneFlowTemplateHelper < OpenNebulaHelper::OneHelper
|
|
|
57
57
|
d['NAME']
|
|
58
58
|
end
|
|
59
59
|
|
|
60
|
-
|
|
60
|
+
column :REGTIME,
|
|
61
|
+
'Registration time of the Service Template',
|
|
62
|
+
:size => 15 do |d|
|
|
63
|
+
d.extend(CLIHelper::HashWithSearch)
|
|
64
|
+
d = d.dsearch('TEMPLATE/BODY')
|
|
65
|
+
|
|
66
|
+
OpenNebulaHelper.time_to_str(d['registration_time'])
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
default :ID, :USER, :GROUP, :NAME, :REGTIME
|
|
61
70
|
end
|
|
62
71
|
end
|
|
63
72
|
|
|
@@ -73,6 +82,8 @@ class OneFlowTemplateHelper < OpenNebulaHelper::OneHelper
|
|
|
73
82
|
else
|
|
74
83
|
if options[:json]
|
|
75
84
|
[0, response.body]
|
|
85
|
+
elsif options[:yaml]
|
|
86
|
+
[0, JSON.parse(response.body).to_yaml(:indent => 4)]
|
|
76
87
|
else
|
|
77
88
|
documents = JSON.parse(response.body)['DOCUMENT_POOL']
|
|
78
89
|
format_service_template_pool.show(documents['DOCUMENT'])
|
|
@@ -120,12 +131,17 @@ class OneFlowTemplateHelper < OpenNebulaHelper::OneHelper
|
|
|
120
131
|
else
|
|
121
132
|
if options[:json]
|
|
122
133
|
[0, response.body]
|
|
134
|
+
elsif options[:yaml]
|
|
135
|
+
[0, JSON.parse(response.body).to_yaml(:indent => 4)]
|
|
123
136
|
else
|
|
124
137
|
str = '%-20s: %-20s'
|
|
125
138
|
str_h1 = '%-80s'
|
|
126
139
|
|
|
127
140
|
document = JSON.parse(response.body)['DOCUMENT']
|
|
128
141
|
template = document['TEMPLATE']['BODY']
|
|
142
|
+
reg_time = OpenNebulaHelper.time_to_str(
|
|
143
|
+
template['registration_time']
|
|
144
|
+
)
|
|
129
145
|
|
|
130
146
|
CLIHelper.print_header(
|
|
131
147
|
str_h1 % "SERVICE TEMPLATE #{document['ID']} INFORMATION"
|
|
@@ -135,6 +151,7 @@ class OneFlowTemplateHelper < OpenNebulaHelper::OneHelper
|
|
|
135
151
|
puts Kernel.format str, 'NAME', document['NAME']
|
|
136
152
|
puts Kernel.format str, 'USER', document['UNAME']
|
|
137
153
|
puts Kernel.format str, 'GROUP', document['GNAME']
|
|
154
|
+
puts Kernel.format str, 'REGISTRATION TIME', reg_time
|
|
138
155
|
|
|
139
156
|
puts
|
|
140
157
|
|
|
@@ -309,4 +326,13 @@ class OneFlowTemplateHelper < OpenNebulaHelper::OneHelper
|
|
|
309
326
|
answers
|
|
310
327
|
end
|
|
311
328
|
|
|
329
|
+
def factory(id = nil)
|
|
330
|
+
if id
|
|
331
|
+
OpenNebula::ServiceTemplate.new_with_id(id, @client)
|
|
332
|
+
else
|
|
333
|
+
xml = OpenNebula::ServiceTemplate.build_xml
|
|
334
|
+
OpenNebula::ServiceTemplate.new(xml, @client)
|
|
335
|
+
end
|
|
336
|
+
end
|
|
337
|
+
|
|
312
338
|
end
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
# -------------------------------------------------------------------------- #
|
|
2
|
-
# Copyright 2002-
|
|
2
|
+
# Copyright 2002-2021, OpenNebula Project, OpenNebula Systems #
|
|
3
3
|
# #
|
|
4
4
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may #
|
|
5
5
|
# not use this file except in compliance with the License. You may obtain #
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
# -------------------------------------------------------------------------- #
|
|
2
|
-
# Copyright 2002-
|
|
2
|
+
# Copyright 2002-2021, OpenNebula Project, OpenNebula Systems #
|
|
3
3
|
# #
|
|
4
4
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may #
|
|
5
5
|
# not use this file except in compliance with the License. You may obtain #
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
# -------------------------------------------------------------------------- #
|
|
2
|
-
# Copyright 2002-
|
|
2
|
+
# Copyright 2002-2021, OpenNebula Project, OpenNebula Systems #
|
|
3
3
|
# #
|
|
4
4
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may #
|
|
5
5
|
# not use this file except in compliance with the License. You may obtain #
|
|
@@ -222,10 +222,6 @@ class OneHostHelper < OpenNebulaHelper::OneHelper
|
|
|
222
222
|
end
|
|
223
223
|
end
|
|
224
224
|
|
|
225
|
-
column :PROVIDER, 'Host provider', :left, :size => 6 do |d|
|
|
226
|
-
d['TEMPLATE']['PM_MAD'].nil? ? '-' : d['TEMPLATE']['PM_MAD']
|
|
227
|
-
end
|
|
228
|
-
|
|
229
225
|
column :STAT, 'Host status', :left, :size => 6 do |d|
|
|
230
226
|
OneHostHelper.state_to_str(d['STATE'])
|
|
231
227
|
end
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
# -------------------------------------------------------------------------- #
|
|
2
|
-
# Copyright 2002-
|
|
2
|
+
# Copyright 2002-2021, OpenNebula Project, OpenNebula Systems #
|
|
3
3
|
# #
|
|
4
4
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may #
|
|
5
5
|
# not use this file except in compliance with the License. You may obtain #
|
|
@@ -22,7 +22,7 @@ class OneImageHelper < OpenNebulaHelper::OneHelper
|
|
|
22
22
|
|
|
23
23
|
# This list contains prefixes that should skip adding user home to the path
|
|
24
24
|
# This must have the same content as the case $FROM in downloader.sh
|
|
25
|
-
PREFIXES = %w[http https ssh s3 rbd vcenter lxd docker]
|
|
25
|
+
PREFIXES = %w[http https ssh s3 rbd vcenter lxd docker dockerfile]
|
|
26
26
|
|
|
27
27
|
TEMPLATE_OPTIONS=[
|
|
28
28
|
{
|
|
@@ -98,9 +98,9 @@ class OneImageHelper < OpenNebulaHelper::OneHelper
|
|
|
98
98
|
end
|
|
99
99
|
},
|
|
100
100
|
{
|
|
101
|
-
:name => '
|
|
102
|
-
:large => '--
|
|
103
|
-
:description => '
|
|
101
|
+
:name => 'format',
|
|
102
|
+
:large => '--format format',
|
|
103
|
+
:description => 'Format of the image (raw, qcow2, ...)',
|
|
104
104
|
:format => String
|
|
105
105
|
},
|
|
106
106
|
{
|
|
@@ -295,7 +295,7 @@ class OneImageHelper < OpenNebulaHelper::OneHelper
|
|
|
295
295
|
str_h1='%-80s'
|
|
296
296
|
|
|
297
297
|
path = image['PATH']
|
|
298
|
-
|
|
298
|
+
iformat = image['FORMAT']
|
|
299
299
|
|
|
300
300
|
size = OpenNebulaHelper.unit_to_str(image['SIZE'].to_i, {}, 'M')
|
|
301
301
|
lock = OpenNebulaHelper.level_lock_to_str(image['LOCK/LOCKED'])
|
|
@@ -314,7 +314,7 @@ class OneImageHelper < OpenNebulaHelper::OneHelper
|
|
|
314
314
|
puts format(str, 'PERSISTENT', pers)
|
|
315
315
|
puts format(str, 'SOURCE', image['SOURCE'])
|
|
316
316
|
puts format(str, 'PATH', path) if path && !path.empty?
|
|
317
|
-
puts format(str, '
|
|
317
|
+
puts format(str, 'FORMAT', iformat) if iformat && !iformat.empty?
|
|
318
318
|
puts format(str, 'SIZE', size)
|
|
319
319
|
puts format(str, 'STATE', image.short_state_str)
|
|
320
320
|
puts format(str, 'RUNNING_VMS', image['RUNNING_VMS'])
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
# -------------------------------------------------------------------------- #
|
|
2
|
-
# Copyright 2002-
|
|
2
|
+
# Copyright 2002-2021, OpenNebula Project, OpenNebula Systems #
|
|
3
3
|
# #
|
|
4
4
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may #
|
|
5
5
|
# not use this file except in compliance with the License. You may obtain #
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
# -------------------------------------------------------------------------- #
|
|
2
|
-
# Copyright 2002-
|
|
2
|
+
# Copyright 2002-2021, OpenNebula Project, OpenNebula Systems #
|
|
3
3
|
# #
|
|
4
4
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may #
|
|
5
5
|
# not use this file except in compliance with the License. You may obtain #
|
|
@@ -15,100 +15,118 @@
|
|
|
15
15
|
#--------------------------------------------------------------------------- #
|
|
16
16
|
|
|
17
17
|
require 'one_helper'
|
|
18
|
+
require 'opennebula/marketplaceapp_ext'
|
|
19
|
+
require 'opennebula/template_ext'
|
|
20
|
+
require 'opennebula/virtual_machine_ext'
|
|
21
|
+
require 'opennebula/flow/service_template_ext'
|
|
18
22
|
|
|
23
|
+
require 'securerandom'
|
|
24
|
+
|
|
25
|
+
# OneMarketApp Command Helper
|
|
19
26
|
class OneMarketPlaceAppHelper < OpenNebulaHelper::OneHelper
|
|
27
|
+
|
|
20
28
|
TEMPLATE_OPTIONS=[
|
|
21
29
|
{
|
|
22
|
-
:name =>
|
|
23
|
-
:large =>
|
|
30
|
+
:name => 'name',
|
|
31
|
+
:large => '--name name',
|
|
24
32
|
:format => String,
|
|
25
|
-
:description =>
|
|
33
|
+
:description => 'Name of the new MarketPlaceApp'
|
|
26
34
|
},
|
|
27
35
|
{
|
|
28
|
-
:name =>
|
|
29
|
-
:large =>
|
|
36
|
+
:name => 'description',
|
|
37
|
+
:large => '--description description',
|
|
30
38
|
:format => String,
|
|
31
|
-
:description =>
|
|
39
|
+
:description => 'Description for the new MarketPlaceApp'
|
|
32
40
|
},
|
|
33
41
|
{
|
|
34
|
-
:name =>
|
|
35
|
-
:large =>
|
|
36
|
-
:description =>
|
|
42
|
+
:name => 'image',
|
|
43
|
+
:large => '--image id|name',
|
|
44
|
+
:description => 'Selects the image',
|
|
37
45
|
:format => String,
|
|
38
|
-
:template_key =>
|
|
39
|
-
:proc => lambda {
|
|
40
|
-
OpenNebulaHelper.rname_to_id(o,
|
|
46
|
+
:template_key => 'origin_id',
|
|
47
|
+
:proc => lambda {|o, _options|
|
|
48
|
+
OpenNebulaHelper.rname_to_id(o, 'IMAGE')
|
|
41
49
|
}
|
|
42
50
|
},
|
|
43
51
|
OpenNebulaHelper::DRY
|
|
44
52
|
]
|
|
45
53
|
|
|
46
54
|
VMNAME = {
|
|
47
|
-
:name =>
|
|
48
|
-
:large =>
|
|
49
|
-
:description =>
|
|
55
|
+
:name => 'vmname',
|
|
56
|
+
:large => '--vmname name',
|
|
57
|
+
:description => 'Selects the name for the new VM Template, ' \
|
|
58
|
+
'if the App contains one',
|
|
50
59
|
:format => String
|
|
51
60
|
}
|
|
52
61
|
|
|
62
|
+
# Available market place mads to import apps on them
|
|
63
|
+
MARKETS = %w[http s3]
|
|
64
|
+
|
|
53
65
|
def self.rname
|
|
54
|
-
|
|
66
|
+
'MARKETPLACEAPP'
|
|
55
67
|
end
|
|
56
68
|
|
|
57
69
|
def self.conf_file
|
|
58
|
-
|
|
70
|
+
'onemarketapp.yaml'
|
|
59
71
|
end
|
|
60
72
|
|
|
61
73
|
def self.state_to_str(id)
|
|
62
74
|
id = id.to_i
|
|
63
75
|
state_str = MarketPlaceApp::MARKETPLACEAPP_STATES[id]
|
|
64
|
-
|
|
76
|
+
MarketPlaceApp::SHORT_MARKETPLACEAPP_STATES[state_str]
|
|
65
77
|
end
|
|
66
78
|
|
|
67
|
-
def format_pool(
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
d[
|
|
79
|
+
def format_pool(_options)
|
|
80
|
+
CLIHelper::ShowTable.new(self.class.table_conf, self) do
|
|
81
|
+
column :ID,
|
|
82
|
+
'ONE identifier for the marketplace app',
|
|
83
|
+
:size=>4 do |d|
|
|
84
|
+
d['ID']
|
|
73
85
|
end
|
|
74
86
|
|
|
75
|
-
column :NAME,
|
|
76
|
-
d[
|
|
87
|
+
column :NAME, 'Name of the marketplace app', :left, :size=>25 do |d|
|
|
88
|
+
d['NAME']
|
|
77
89
|
end
|
|
78
90
|
|
|
79
|
-
column :VERSION,
|
|
80
|
-
d[
|
|
91
|
+
column :VERSION, 'Version of the app', :size=>10 do |d|
|
|
92
|
+
d['VERSION']
|
|
81
93
|
end
|
|
82
94
|
|
|
83
|
-
column :SIZE,
|
|
95
|
+
column :SIZE, 'App size', :size =>5 do |d|
|
|
84
96
|
OpenNebulaHelper.unit_to_str(d['SIZE'].to_i, {}, 'M')
|
|
85
97
|
end
|
|
86
98
|
|
|
87
|
-
column :STAT,
|
|
88
|
-
OneMarketPlaceAppHelper.state_to_str(d[
|
|
99
|
+
column :STAT, 'State of the app', :size=>4 do |d|
|
|
100
|
+
OneMarketPlaceAppHelper.state_to_str(d['STATE'])
|
|
89
101
|
end
|
|
90
102
|
|
|
91
|
-
column :REGTIME,
|
|
92
|
-
Time.at(d['REGTIME'].to_i).strftime(
|
|
103
|
+
column :REGTIME, 'Registration time of the app', :size=>8 do |d|
|
|
104
|
+
Time.at(d['REGTIME'].to_i).strftime('%D')
|
|
93
105
|
end
|
|
94
106
|
|
|
95
|
-
column :TYPE,
|
|
96
|
-
type = MarketPlaceApp::MARKETPLACEAPP_TYPES[d[
|
|
107
|
+
column :TYPE, 'Marketplace app type', :size=>4 do |d|
|
|
108
|
+
type = MarketPlaceApp::MARKETPLACEAPP_TYPES[d['TYPE'].to_i]
|
|
97
109
|
MarketPlaceApp::SHORT_MARKETPLACEAPP_TYPES[type]
|
|
98
110
|
end
|
|
99
111
|
|
|
100
|
-
column :MARKET,
|
|
101
|
-
d[
|
|
112
|
+
column :MARKET, 'Name of the MarketPlace', :left, :size=>20 do |d|
|
|
113
|
+
d['MARKETPLACE']
|
|
102
114
|
end
|
|
103
115
|
|
|
104
|
-
column :ZONE,
|
|
105
|
-
d[
|
|
116
|
+
column :ZONE, 'Zone ID', :size=>4 do |d|
|
|
117
|
+
d['ZONE_ID']
|
|
106
118
|
end
|
|
107
119
|
|
|
108
|
-
default :ID
|
|
120
|
+
default :ID,
|
|
121
|
+
:NAME,
|
|
122
|
+
:VERSION,
|
|
123
|
+
:SIZE,
|
|
124
|
+
:STAT,
|
|
125
|
+
:TYPE,
|
|
126
|
+
:REGTIME,
|
|
127
|
+
:MARKET,
|
|
128
|
+
:ZONE
|
|
109
129
|
end
|
|
110
|
-
|
|
111
|
-
table
|
|
112
130
|
end
|
|
113
131
|
|
|
114
132
|
def self.create_template_options_used?(options)
|
|
@@ -123,9 +141,236 @@ class OneMarketPlaceAppHelper < OpenNebulaHelper::OneHelper
|
|
|
123
141
|
(template_options-options.keys)!=template_options
|
|
124
142
|
end
|
|
125
143
|
|
|
144
|
+
# Import object into marketplace
|
|
145
|
+
#
|
|
146
|
+
# @param object [String] Object ID or name
|
|
147
|
+
# @param o_class [Class] Object class
|
|
148
|
+
def import(object, o_class)
|
|
149
|
+
id = get_obj_id(object, o_class)
|
|
150
|
+
|
|
151
|
+
if OpenNebula.is_error?(id)
|
|
152
|
+
STDERR.puts id.message
|
|
153
|
+
exit(-1)
|
|
154
|
+
end
|
|
155
|
+
|
|
156
|
+
rc = yield(id) if block_given?
|
|
157
|
+
|
|
158
|
+
if OpenNebula.is_error?(rc)
|
|
159
|
+
STDERR.puts rc.message
|
|
160
|
+
exit(-1)
|
|
161
|
+
elsif rc[0] == -1
|
|
162
|
+
STDERR.puts rc[1]
|
|
163
|
+
exit(-1)
|
|
164
|
+
end
|
|
165
|
+
|
|
166
|
+
0
|
|
167
|
+
end
|
|
168
|
+
|
|
169
|
+
# Import service template into marketplace
|
|
170
|
+
#
|
|
171
|
+
# @param id [Integer] Service Template ID
|
|
172
|
+
# @param options [Hash] User CLI options
|
|
173
|
+
#
|
|
174
|
+
# @return [Error code, error message] 0 if everything was correct
|
|
175
|
+
# 1 otherwhise
|
|
176
|
+
def import_service_template(id, options)
|
|
177
|
+
require 'json'
|
|
178
|
+
|
|
179
|
+
pool = private_markets
|
|
180
|
+
|
|
181
|
+
return pool if OpenNebula.is_error?(pool)
|
|
182
|
+
|
|
183
|
+
s_template = ServiceTemplate.new_with_id(id, @client)
|
|
184
|
+
rc = s_template.info
|
|
185
|
+
|
|
186
|
+
return rc if OpenNebula.is_error?(rc)
|
|
187
|
+
|
|
188
|
+
body = JSON.parse(s_template.to_json)['DOCUMENT']['TEMPLATE']['BODY']
|
|
189
|
+
import_all = options[:yes] || options[:no]
|
|
190
|
+
|
|
191
|
+
while import_all != 'no' && import_all != 'yes'
|
|
192
|
+
print 'Do you want to import images too? (yes/no, default=yes): '
|
|
193
|
+
import_all = STDIN.readline.chop.downcase
|
|
194
|
+
|
|
195
|
+
if import_all.empty?
|
|
196
|
+
puts 'yes'
|
|
197
|
+
import_all = 'yes'
|
|
198
|
+
end
|
|
199
|
+
end
|
|
200
|
+
|
|
201
|
+
main_market = options[:market]
|
|
202
|
+
|
|
203
|
+
# Read marketplace where import the service template
|
|
204
|
+
# It can only be a private marketplace
|
|
205
|
+
unless main_market
|
|
206
|
+
puts
|
|
207
|
+
puts 'Available Marketplaces (please enter ID)'
|
|
208
|
+
pool.each {|market| puts "- #{market['ID']}: #{market['NAME']}" }
|
|
209
|
+
puts
|
|
210
|
+
end
|
|
211
|
+
|
|
212
|
+
default_mp = pool.first['ID'].to_i
|
|
213
|
+
|
|
214
|
+
# Keep asking while user selects an incorrect marketplace
|
|
215
|
+
until OneMarketPlaceAppHelper.market_exist?(pool, main_market)
|
|
216
|
+
print 'Where do you want to import the Service template? ' \
|
|
217
|
+
"(default=#{default_mp})"
|
|
218
|
+
main_market = STDIN.readline.chop
|
|
219
|
+
|
|
220
|
+
if main_market.empty?
|
|
221
|
+
puts default_mp
|
|
222
|
+
main_market = default_mp
|
|
223
|
+
else
|
|
224
|
+
main_market = main_market.to_i
|
|
225
|
+
end
|
|
226
|
+
end
|
|
227
|
+
|
|
228
|
+
markets = import_service_template_roles(import_all,
|
|
229
|
+
body,
|
|
230
|
+
pool,
|
|
231
|
+
options[:market])
|
|
232
|
+
ids = []
|
|
233
|
+
|
|
234
|
+
# Create roles apps
|
|
235
|
+
if import_all == 'yes'
|
|
236
|
+
rc = create_apps(markets, import_all)
|
|
237
|
+
ids = rc[1]
|
|
238
|
+
|
|
239
|
+
return [-1, rc[0]] unless rc[0].empty?
|
|
240
|
+
end
|
|
241
|
+
|
|
242
|
+
# Create service template app
|
|
243
|
+
s_template.extend(ServiceTemplateExt)
|
|
244
|
+
|
|
245
|
+
rc = s_template.mp_import(markets, main_market, options[:vmname])
|
|
246
|
+
|
|
247
|
+
if rc[0] == -1
|
|
248
|
+
rc
|
|
249
|
+
else
|
|
250
|
+
ids.each {|i| puts "ID: #{i}" }
|
|
251
|
+
puts "ID: #{rc[1]}"
|
|
252
|
+
[0, nil]
|
|
253
|
+
end
|
|
254
|
+
end
|
|
255
|
+
|
|
256
|
+
# Import VM Template into marketplace
|
|
257
|
+
#
|
|
258
|
+
# @param id [Integer] VM Template ID
|
|
259
|
+
# @param options [Hash] User CLI options
|
|
260
|
+
#
|
|
261
|
+
# @return [Error code, error message] 0 if everything was correct
|
|
262
|
+
# 1 otherwhise
|
|
263
|
+
def import_vm_template(id, options)
|
|
264
|
+
pool = private_markets
|
|
265
|
+
|
|
266
|
+
return pool if OpenNebula.is_error?(pool)
|
|
267
|
+
|
|
268
|
+
template = Template.new_with_id(id, @client)
|
|
269
|
+
rc = template.info
|
|
270
|
+
|
|
271
|
+
return rc if OpenNebula.is_error?(rc)
|
|
272
|
+
|
|
273
|
+
import_all = options[:yes] || options[:no]
|
|
274
|
+
|
|
275
|
+
while import_all != 'no' && import_all != 'yes'
|
|
276
|
+
print 'Do you want to import images too? (yes/no, default=yes): '
|
|
277
|
+
import_all = STDIN.readline.chop.downcase
|
|
278
|
+
|
|
279
|
+
if import_all.empty?
|
|
280
|
+
puts 'yes'
|
|
281
|
+
import_all = 'yes'
|
|
282
|
+
end
|
|
283
|
+
end
|
|
284
|
+
|
|
285
|
+
main_market = options[:market]
|
|
286
|
+
|
|
287
|
+
# Read marketplace where import the VM template
|
|
288
|
+
# It can only be a private marketplace
|
|
289
|
+
unless main_market
|
|
290
|
+
puts
|
|
291
|
+
puts 'Available Marketplaces (please enter ID)'
|
|
292
|
+
pool.each {|market| puts "- #{market['ID']}: #{market['NAME']}" }
|
|
293
|
+
puts
|
|
294
|
+
end
|
|
295
|
+
|
|
296
|
+
default_mp = pool.first['ID'].to_i
|
|
297
|
+
|
|
298
|
+
# Keep asking while user selects an incorrect marketplace
|
|
299
|
+
until OneMarketPlaceAppHelper.market_exist?(pool, main_market)
|
|
300
|
+
print 'Where do you want to import the VM template? ' \
|
|
301
|
+
"(default=#{default_mp})"
|
|
302
|
+
main_market = STDIN.readline.chop
|
|
303
|
+
|
|
304
|
+
if main_market.empty?
|
|
305
|
+
puts default_mp
|
|
306
|
+
main_market = default_mp
|
|
307
|
+
else
|
|
308
|
+
main_market = main_market.to_i
|
|
309
|
+
end
|
|
310
|
+
end
|
|
311
|
+
|
|
312
|
+
# Templates import information
|
|
313
|
+
#
|
|
314
|
+
# template_id => :market => marketplace ID to import it
|
|
315
|
+
# :template => ONE Template information
|
|
316
|
+
# :name => generated name for the template
|
|
317
|
+
markets = {}
|
|
318
|
+
markets[template['ID']] = {}
|
|
319
|
+
markets[template['ID']][:market] = main_market
|
|
320
|
+
markets[template['ID']][:template] = template
|
|
321
|
+
|
|
322
|
+
rc = create_apps(markets, import_all, options[:vmname])
|
|
323
|
+
|
|
324
|
+
if rc[0] == -1
|
|
325
|
+
rc
|
|
326
|
+
else
|
|
327
|
+
rc[1].each {|i| puts "ID: #{i}" }
|
|
328
|
+
[0, nil]
|
|
329
|
+
end
|
|
330
|
+
end
|
|
331
|
+
|
|
332
|
+
# Save VM as template to be able to import it
|
|
333
|
+
#
|
|
334
|
+
# @param id [Integer] VM ID
|
|
335
|
+
#
|
|
336
|
+
# @return [Integer] New template ID
|
|
337
|
+
def save_as_template(id)
|
|
338
|
+
vm = VirtualMachine.new_with_id(id, @client)
|
|
339
|
+
rc = vm.info
|
|
340
|
+
|
|
341
|
+
return rc if OpenNebula.is_error?(rc)
|
|
342
|
+
|
|
343
|
+
vm.extend(VirtualMachineExt)
|
|
344
|
+
|
|
345
|
+
vm.save_as_template("#{vm['NAME']}-saved", 'App to import')
|
|
346
|
+
end
|
|
347
|
+
|
|
348
|
+
# Get object ID from name
|
|
349
|
+
#
|
|
350
|
+
# @param id [String] ID or NAME
|
|
351
|
+
# @param obj [OpenNebula::Class] OpenNebula pool class
|
|
352
|
+
#
|
|
353
|
+
# @return [Integer] Object ID
|
|
354
|
+
def get_obj_id(id, obj)
|
|
355
|
+
if (id.is_a? Integer) || id.match(/^\d+$/)
|
|
356
|
+
id.to_i
|
|
357
|
+
else
|
|
358
|
+
pool = obj.new(@client)
|
|
359
|
+
rc = pool.info_all
|
|
360
|
+
|
|
361
|
+
return rc if OpenNebula.is_error?(rc)
|
|
362
|
+
|
|
363
|
+
rc = pool.find {|v| v['NAME'] == id }
|
|
364
|
+
|
|
365
|
+
return Error.new("Object `#{id}` not found") unless rc
|
|
366
|
+
|
|
367
|
+
rc['ID'].to_i
|
|
368
|
+
end
|
|
369
|
+
end
|
|
370
|
+
|
|
126
371
|
private
|
|
127
372
|
|
|
128
|
-
def factory(id=nil)
|
|
373
|
+
def factory(id = nil)
|
|
129
374
|
if id
|
|
130
375
|
OpenNebula::MarketPlaceApp.new_with_id(id, @client)
|
|
131
376
|
else
|
|
@@ -134,91 +379,244 @@ class OneMarketPlaceAppHelper < OpenNebulaHelper::OneHelper
|
|
|
134
379
|
end
|
|
135
380
|
end
|
|
136
381
|
|
|
137
|
-
def factory_pool(user_flag
|
|
382
|
+
def factory_pool(user_flag = -2)
|
|
138
383
|
OpenNebula::MarketPlaceAppPool.new(@client, user_flag)
|
|
139
384
|
end
|
|
140
385
|
|
|
141
|
-
def format_resource(app,
|
|
142
|
-
str=
|
|
143
|
-
str_h1=
|
|
144
|
-
|
|
145
|
-
CLIHelper.print_header(
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
puts str
|
|
149
|
-
puts str
|
|
150
|
-
puts str
|
|
151
|
-
puts str
|
|
152
|
-
puts str
|
|
153
|
-
puts str
|
|
386
|
+
def format_resource(app, _options = {})
|
|
387
|
+
str='%-15s: %-20s'
|
|
388
|
+
str_h1='%-80s'
|
|
389
|
+
|
|
390
|
+
CLIHelper.print_header(
|
|
391
|
+
str_h1 % "MARKETPLACE APP #{app['ID']} INFORMATION"
|
|
392
|
+
)
|
|
393
|
+
puts format(str, 'ID', app.id.to_s)
|
|
394
|
+
puts format(str, 'NAME', app.name)
|
|
395
|
+
puts format(str, 'TYPE', app.type_str)
|
|
396
|
+
puts format(str, 'USER', app['UNAME'])
|
|
397
|
+
puts format(str, 'GROUP', app['GNAME'])
|
|
398
|
+
puts format(str, 'MARKETPLACE', app['MARKETPLACE'])
|
|
399
|
+
puts format(str,
|
|
400
|
+
'STATE',
|
|
401
|
+
OneMarketPlaceAppHelper.state_to_str(app['STATE']))
|
|
402
|
+
puts format(str,
|
|
403
|
+
'LOCK',
|
|
404
|
+
OpenNebulaHelper.level_lock_to_str(app['LOCK/LOCKED']))
|
|
154
405
|
|
|
155
406
|
puts
|
|
156
407
|
|
|
157
|
-
CLIHelper.print_header(str_h1 %
|
|
408
|
+
CLIHelper.print_header(str_h1 % 'PERMISSIONS', false)
|
|
158
409
|
|
|
159
|
-
[
|
|
160
|
-
mask =
|
|
161
|
-
mask[0] =
|
|
162
|
-
mask[1] =
|
|
163
|
-
mask[2] =
|
|
410
|
+
%w[OWNER GROUP OTHER].each do |e|
|
|
411
|
+
mask = '---'
|
|
412
|
+
mask[0] = 'u' if app["PERMISSIONS/#{e}_U"] == '1'
|
|
413
|
+
mask[1] = 'm' if app["PERMISSIONS/#{e}_M"] == '1'
|
|
414
|
+
mask[2] = 'a' if app["PERMISSIONS/#{e}_A"] == '1'
|
|
164
415
|
|
|
165
|
-
puts str
|
|
166
|
-
|
|
416
|
+
puts format(str, e, mask)
|
|
417
|
+
end
|
|
167
418
|
puts
|
|
168
419
|
|
|
169
|
-
CLIHelper.print_header(str_h1 %
|
|
170
|
-
|
|
171
|
-
puts str
|
|
172
|
-
puts str
|
|
173
|
-
puts str
|
|
174
|
-
puts str
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
puts str
|
|
178
|
-
puts str
|
|
179
|
-
puts str
|
|
420
|
+
CLIHelper.print_header(str_h1 % 'DETAILS', false)
|
|
421
|
+
|
|
422
|
+
puts format(str, 'SOURCE', app['SOURCE'])
|
|
423
|
+
puts format(str, 'MD5', app['MD5'])
|
|
424
|
+
puts format(str, 'PUBLISHER', app['PUBLISHER'])
|
|
425
|
+
puts format(str,
|
|
426
|
+
'REGISTER TIME',
|
|
427
|
+
Time.at(app['REGTIME'].to_i).strftime('%c'))
|
|
428
|
+
puts format(str, 'VERSION', app['VERSION'])
|
|
429
|
+
puts format(str, 'DESCRIPTION', app['DESCRIPTION'])
|
|
430
|
+
puts format(str,
|
|
431
|
+
'SIZE',
|
|
432
|
+
OpenNebulaHelper.unit_to_str(app['SIZE'].to_i, {}, 'M'))
|
|
433
|
+
puts format(str, 'ORIGIN_ID', app['ORIGIN_ID'])
|
|
434
|
+
puts format(str, 'FORMAT', app['FORMAT'])
|
|
180
435
|
|
|
181
436
|
puts
|
|
182
437
|
|
|
183
|
-
CLIHelper.print_header(str_h1 %
|
|
438
|
+
CLIHelper.print_header(str_h1 % 'IMPORT TEMPLATE', false)
|
|
184
439
|
|
|
185
440
|
puts Base64.decode64(app['APPTEMPLATE64'])
|
|
186
441
|
|
|
187
442
|
puts
|
|
188
443
|
|
|
189
|
-
CLIHelper.print_header(str_h1 %
|
|
444
|
+
CLIHelper.print_header(str_h1 % 'MARKETPLACE APP TEMPLATE', false)
|
|
190
445
|
puts app.template_str
|
|
191
446
|
|
|
192
447
|
puts
|
|
193
448
|
end
|
|
194
449
|
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
450
|
+
class << self
|
|
451
|
+
|
|
452
|
+
def create_variables(options, name)
|
|
453
|
+
names = [name].flatten
|
|
454
|
+
t = ''
|
|
455
|
+
|
|
456
|
+
names.each do |n|
|
|
457
|
+
next unless options[n]
|
|
458
|
+
|
|
459
|
+
t << "#{n.to_s.upcase}=\"#{options[n]}\"\n"
|
|
460
|
+
end
|
|
461
|
+
|
|
462
|
+
t
|
|
200
463
|
end
|
|
201
464
|
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
t<<"#{n.to_s.upcase}=\"#{options[n]}\"\n"
|
|
465
|
+
def create_datastore_template(options)
|
|
466
|
+
template_options = TEMPLATE_OPTIONS.map do |o|
|
|
467
|
+
o[:name].to_sym
|
|
206
468
|
end
|
|
469
|
+
|
|
470
|
+
template = create_variables(options,
|
|
471
|
+
template_options-[:dry, :image])
|
|
472
|
+
|
|
473
|
+
template << "ORIGIN_ID=#{options[:image]}\n" if options[:image]
|
|
474
|
+
template << "TYPE=image\n"
|
|
475
|
+
|
|
476
|
+
[0, template]
|
|
477
|
+
end
|
|
478
|
+
|
|
479
|
+
# Check if marketplace exists
|
|
480
|
+
#
|
|
481
|
+
# @param pool [MarketPlacePool] Marketplaces pool
|
|
482
|
+
# @param market [String] ID to check
|
|
483
|
+
#
|
|
484
|
+
# @return [Boolean] True if exists, false otherwise
|
|
485
|
+
def market_exist?(pool, market)
|
|
486
|
+
!pool.select {|v| v['ID'].to_i == market }.empty?
|
|
207
487
|
end
|
|
208
488
|
|
|
209
|
-
t
|
|
210
489
|
end
|
|
211
490
|
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
491
|
+
# Get private marketplace to import templates
|
|
492
|
+
#
|
|
493
|
+
# @return [OpenNebula::Pool] Marketplace pool or error if any
|
|
494
|
+
def private_markets
|
|
495
|
+
pool = MarketPlacePool.new(@client)
|
|
496
|
+
rc = pool.info
|
|
497
|
+
|
|
498
|
+
return rc if OpenNebula.is_error?(rc)
|
|
499
|
+
|
|
500
|
+
# Get private marketplaces
|
|
501
|
+
pool = pool.select {|market| MARKETS.include?(market['MARKET_MAD']) }
|
|
502
|
+
pool = pool.sort_by {|market| market['ID'].to_i }
|
|
503
|
+
|
|
504
|
+
if pool.empty?
|
|
505
|
+
return Error.new("There are no #{MARKETS.join('/')} marketplaces")
|
|
506
|
+
end
|
|
507
|
+
|
|
508
|
+
pool
|
|
509
|
+
end
|
|
510
|
+
|
|
511
|
+
# Get roles information when importing a service template into marketplace
|
|
512
|
+
#
|
|
513
|
+
# @param import_all [String] yes to import VM templates too, no otherwise
|
|
514
|
+
# @param body [Hash] Sevice Template information
|
|
515
|
+
# @param pool [Array] Marketplace pool
|
|
516
|
+
# @param market [Integer] Marketplace to import
|
|
517
|
+
#
|
|
518
|
+
# @return [Hash] Roles templates and marketplaces to import them
|
|
519
|
+
def import_service_template_roles(import_all, body, pool, market)
|
|
520
|
+
# Templates import information
|
|
521
|
+
#
|
|
522
|
+
# template_id => :market => marketplace ID to import it
|
|
523
|
+
# :template => ONE Template information
|
|
524
|
+
# :name => generated name for the template
|
|
525
|
+
markets = {}
|
|
526
|
+
default_mp = pool.first['ID'].to_i
|
|
527
|
+
|
|
528
|
+
if import_all == 'yes'
|
|
529
|
+
# Read marketplace where import each different VM template
|
|
530
|
+
# It can only be a private marketplace
|
|
531
|
+
unless market
|
|
532
|
+
puts
|
|
533
|
+
puts 'Available Marketplaces for roles (please enter ID)'
|
|
534
|
+
pool.each do |m|
|
|
535
|
+
puts "- #{m['ID']}: #{m['NAME']}"
|
|
536
|
+
end
|
|
537
|
+
puts
|
|
538
|
+
end
|
|
539
|
+
|
|
540
|
+
# Iterate all the roles to ask for the marketplace
|
|
541
|
+
body['roles'].each do |role|
|
|
542
|
+
# Read role VM template information from OpenNebula
|
|
543
|
+
template = Template.new_with_id(role['vm_template'], @client)
|
|
544
|
+
rc = template.info
|
|
545
|
+
|
|
546
|
+
return rc if OpenNebula.is_error?(rc)
|
|
547
|
+
|
|
548
|
+
next if markets.include?(template['ID'])
|
|
549
|
+
|
|
550
|
+
if market
|
|
551
|
+
m = market
|
|
552
|
+
else
|
|
553
|
+
# Keep asking while user selects an incorrect marketplace
|
|
554
|
+
until OneMarketPlaceAppHelper.market_exist?(pool, m)
|
|
555
|
+
print 'Where do you want to import' \
|
|
556
|
+
"`#{template['NAME']}`? (default=#{default_mp})"
|
|
557
|
+
m = STDIN.readline.chop
|
|
558
|
+
|
|
559
|
+
if m.empty?
|
|
560
|
+
puts default_mp
|
|
561
|
+
m = default_mp
|
|
562
|
+
else
|
|
563
|
+
m = m.to_i
|
|
564
|
+
end
|
|
565
|
+
end
|
|
566
|
+
end
|
|
567
|
+
|
|
568
|
+
# Update current template information
|
|
569
|
+
markets[template['ID']] = {}
|
|
570
|
+
markets[template['ID']][:market] = m
|
|
571
|
+
markets[template['ID']][:template] = template
|
|
572
|
+
end
|
|
573
|
+
else
|
|
574
|
+
# Do not ask for marketplaces, just fill templates information
|
|
575
|
+
body['roles'].each do |role|
|
|
576
|
+
# Read role VM template information from OpenNebula
|
|
577
|
+
template = Template.new_with_id(role['vm_template'], @client)
|
|
578
|
+
rc = template.info
|
|
579
|
+
|
|
580
|
+
return rc if OpenNebula.is_error?(rc)
|
|
581
|
+
|
|
582
|
+
next if markets.include?(template['ID'])
|
|
583
|
+
|
|
584
|
+
# update current template information
|
|
585
|
+
markets[template['id']] = {}
|
|
586
|
+
markets[template['id']][:template] = template
|
|
587
|
+
end
|
|
215
588
|
end
|
|
216
589
|
|
|
217
|
-
|
|
590
|
+
markets
|
|
591
|
+
end
|
|
592
|
+
|
|
593
|
+
# Create applications in Marketplace
|
|
594
|
+
#
|
|
595
|
+
# @param markets [Hash] Marketplaces and templates information
|
|
596
|
+
# @param import_all [String] yes to import images too, no otherwise
|
|
597
|
+
# @param template_name [String] Virtual Machine Template app name
|
|
598
|
+
#
|
|
599
|
+
# @return [String] Error message in case of any
|
|
600
|
+
def create_apps(markets, import_all, template_name = nil)
|
|
601
|
+
ids = nil
|
|
602
|
+
|
|
603
|
+
markets.each do |_, market|
|
|
604
|
+
template = market[:template]
|
|
605
|
+
|
|
606
|
+
template.extend(OpenNebula::TemplateExt)
|
|
607
|
+
|
|
608
|
+
rc, ids = template.mp_import(market[:market].to_i,
|
|
609
|
+
import_all,
|
|
610
|
+
template_name)
|
|
218
611
|
|
|
219
|
-
|
|
220
|
-
template << "TYPE=image\n"
|
|
612
|
+
return [rc.message, ids] if OpenNebula.is_error?(rc)
|
|
221
613
|
|
|
222
|
-
|
|
614
|
+
# Store name to use it after
|
|
615
|
+
market[:name] = nil
|
|
616
|
+
market[:name] = rc
|
|
617
|
+
end
|
|
618
|
+
|
|
619
|
+
['', ids]
|
|
223
620
|
end
|
|
621
|
+
|
|
224
622
|
end
|