opennebula-cli 5.12.7 → 6.0.0
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 +10 -7
- data/bin/oneimage +100 -9
- data/bin/onemarket +10 -7
- data/bin/onemarketapp +114 -11
- data/bin/onesecgroup +13 -7
- data/bin/oneshowback +18 -10
- data/bin/onetemplate +12 -8
- data/bin/oneuser +30 -7
- data/bin/onevcenter +16 -8
- data/bin/onevdc +10 -7
- data/bin/onevm +147 -12
- data/bin/onevmgroup +13 -7
- data/bin/onevnet +8 -5
- data/bin/onevntemplate +11 -7
- data/bin/onevrouter +10 -7
- data/bin/onezone +11 -8
- data/lib/cli_helper.rb +17 -8
- 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 +13 -7
- data/lib/one_helper/onemarket_helper.rb +1 -1
- data/lib/one_helper/onemarketapp_helper.rb +500 -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 +24 -17
- 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 +50 -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/monitoring_data.xsd +41 -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 +79 -17
- 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,15 @@ 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
|
+
:format => String
|
|
105
|
+
},
|
|
106
|
+
{
|
|
107
|
+
:name => 'fs',
|
|
108
|
+
:large => '--fs filesystem',
|
|
109
|
+
:description => 'Filesystem to format the image (ext4, xfs, ...)',
|
|
104
110
|
:format => String
|
|
105
111
|
},
|
|
106
112
|
{
|
|
@@ -295,7 +301,7 @@ class OneImageHelper < OpenNebulaHelper::OneHelper
|
|
|
295
301
|
str_h1='%-80s'
|
|
296
302
|
|
|
297
303
|
path = image['PATH']
|
|
298
|
-
|
|
304
|
+
iformat = image['FORMAT']
|
|
299
305
|
|
|
300
306
|
size = OpenNebulaHelper.unit_to_str(image['SIZE'].to_i, {}, 'M')
|
|
301
307
|
lock = OpenNebulaHelper.level_lock_to_str(image['LOCK/LOCKED'])
|
|
@@ -314,7 +320,7 @@ class OneImageHelper < OpenNebulaHelper::OneHelper
|
|
|
314
320
|
puts format(str, 'PERSISTENT', pers)
|
|
315
321
|
puts format(str, 'SOURCE', image['SOURCE'])
|
|
316
322
|
puts format(str, 'PATH', path) if path && !path.empty?
|
|
317
|
-
puts format(str, '
|
|
323
|
+
puts format(str, 'FORMAT', iformat) if iformat && !iformat.empty?
|
|
318
324
|
puts format(str, 'SIZE', size)
|
|
319
325
|
puts format(str, 'STATE', image.short_state_str)
|
|
320
326
|
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,242 @@ 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
|
+
# Turn import all into a boolean
|
|
202
|
+
import_all == 'yes' ? import_all = true : import_all = false
|
|
203
|
+
|
|
204
|
+
main_market = options[:market]
|
|
205
|
+
|
|
206
|
+
# Read marketplace where import the service template
|
|
207
|
+
# It can only be a private marketplace
|
|
208
|
+
unless main_market
|
|
209
|
+
puts
|
|
210
|
+
puts 'Available Marketplaces (please enter ID)'
|
|
211
|
+
pool.each {|market| puts "- #{market['ID']}: #{market['NAME']}" }
|
|
212
|
+
puts
|
|
213
|
+
end
|
|
214
|
+
|
|
215
|
+
default_mp = pool.first['ID'].to_i
|
|
216
|
+
|
|
217
|
+
# Keep asking while user selects an incorrect marketplace
|
|
218
|
+
until OneMarketPlaceAppHelper.market_exist?(pool, main_market)
|
|
219
|
+
print 'Where do you want to import the Service template? ' \
|
|
220
|
+
"(default=#{default_mp})"
|
|
221
|
+
main_market = STDIN.readline.chop
|
|
222
|
+
|
|
223
|
+
if main_market.empty?
|
|
224
|
+
puts default_mp
|
|
225
|
+
main_market = default_mp
|
|
226
|
+
else
|
|
227
|
+
main_market = main_market.to_i
|
|
228
|
+
end
|
|
229
|
+
end
|
|
230
|
+
|
|
231
|
+
markets = import_service_template_roles(import_all,
|
|
232
|
+
body,
|
|
233
|
+
pool,
|
|
234
|
+
options[:market])
|
|
235
|
+
ids = []
|
|
236
|
+
|
|
237
|
+
# Create roles apps
|
|
238
|
+
if import_all
|
|
239
|
+
rc = create_apps(markets, import_all)
|
|
240
|
+
ids = rc[1]
|
|
241
|
+
|
|
242
|
+
return [-1, rc[0]] unless rc[0].empty?
|
|
243
|
+
end
|
|
244
|
+
|
|
245
|
+
# Create service template app
|
|
246
|
+
s_template.extend(ServiceTemplateExt)
|
|
247
|
+
|
|
248
|
+
rc = s_template.mp_import(markets, main_market, options[:vmname])
|
|
249
|
+
|
|
250
|
+
if rc[0] == -1
|
|
251
|
+
rc
|
|
252
|
+
else
|
|
253
|
+
ids.each {|i| puts "ID: #{i}" }
|
|
254
|
+
puts "ID: #{rc[1]}"
|
|
255
|
+
[0, nil]
|
|
256
|
+
end
|
|
257
|
+
end
|
|
258
|
+
|
|
259
|
+
# Import VM Template into marketplace
|
|
260
|
+
#
|
|
261
|
+
# @param id [Integer] VM Template ID
|
|
262
|
+
# @param options [Hash] User CLI options
|
|
263
|
+
#
|
|
264
|
+
# @return [Error code, error message] 0 if everything was correct
|
|
265
|
+
# 1 otherwhise
|
|
266
|
+
def import_vm_template(id, options)
|
|
267
|
+
pool = private_markets
|
|
268
|
+
|
|
269
|
+
return pool if OpenNebula.is_error?(pool)
|
|
270
|
+
|
|
271
|
+
template = Template.new_with_id(id, @client)
|
|
272
|
+
rc = template.info
|
|
273
|
+
|
|
274
|
+
return rc if OpenNebula.is_error?(rc)
|
|
275
|
+
|
|
276
|
+
import_all = options[:yes] || options[:no]
|
|
277
|
+
|
|
278
|
+
while import_all != 'no' && import_all != 'yes'
|
|
279
|
+
print 'Do you want to import images too? (yes/no, default=yes): '
|
|
280
|
+
import_all = STDIN.readline.chop.downcase
|
|
281
|
+
|
|
282
|
+
if import_all.empty?
|
|
283
|
+
puts 'yes'
|
|
284
|
+
import_all = 'yes'
|
|
285
|
+
end
|
|
286
|
+
end
|
|
287
|
+
|
|
288
|
+
# Turn import all into a boolean
|
|
289
|
+
import_all == 'yes' ? import_all = true : import_all = false
|
|
290
|
+
|
|
291
|
+
main_market = options[:market]
|
|
292
|
+
|
|
293
|
+
# Read marketplace where import the VM template
|
|
294
|
+
# It can only be a private marketplace
|
|
295
|
+
unless main_market
|
|
296
|
+
puts
|
|
297
|
+
puts 'Available Marketplaces (please enter ID)'
|
|
298
|
+
pool.each {|market| puts "- #{market['ID']}: #{market['NAME']}" }
|
|
299
|
+
puts
|
|
300
|
+
end
|
|
301
|
+
|
|
302
|
+
default_mp = pool.first['ID'].to_i
|
|
303
|
+
|
|
304
|
+
# Keep asking while user selects an incorrect marketplace
|
|
305
|
+
until OneMarketPlaceAppHelper.market_exist?(pool, main_market)
|
|
306
|
+
print 'Where do you want to import the VM template? ' \
|
|
307
|
+
"(default=#{default_mp})"
|
|
308
|
+
main_market = STDIN.readline.chop
|
|
309
|
+
|
|
310
|
+
if main_market.empty?
|
|
311
|
+
puts default_mp
|
|
312
|
+
main_market = default_mp
|
|
313
|
+
else
|
|
314
|
+
main_market = main_market.to_i
|
|
315
|
+
end
|
|
316
|
+
end
|
|
317
|
+
|
|
318
|
+
# Templates import information
|
|
319
|
+
#
|
|
320
|
+
# template_id => :market => marketplace ID to import it
|
|
321
|
+
# :template => ONE Template information
|
|
322
|
+
# :name => generated name for the template
|
|
323
|
+
markets = {}
|
|
324
|
+
markets[template['ID']] = {}
|
|
325
|
+
markets[template['ID']][:market] = main_market
|
|
326
|
+
markets[template['ID']][:template] = template
|
|
327
|
+
|
|
328
|
+
rc = create_apps(markets, import_all, options[:vmname])
|
|
329
|
+
|
|
330
|
+
if rc[0] == -1
|
|
331
|
+
rc
|
|
332
|
+
else
|
|
333
|
+
rc[1].each {|i| puts "ID: #{i}" }
|
|
334
|
+
[0, nil]
|
|
335
|
+
end
|
|
336
|
+
end
|
|
337
|
+
|
|
338
|
+
# Save VM as template to be able to import it
|
|
339
|
+
#
|
|
340
|
+
# @param id [Integer] VM ID
|
|
341
|
+
#
|
|
342
|
+
# @return [Integer] New template ID
|
|
343
|
+
def save_as_template(id)
|
|
344
|
+
vm = VirtualMachine.new_with_id(id, @client)
|
|
345
|
+
rc = vm.info
|
|
346
|
+
|
|
347
|
+
return rc if OpenNebula.is_error?(rc)
|
|
348
|
+
|
|
349
|
+
vm.extend(VirtualMachineExt)
|
|
350
|
+
|
|
351
|
+
vm.save_as_template("#{vm['NAME']}-saved", 'App to import')
|
|
352
|
+
end
|
|
353
|
+
|
|
354
|
+
# Get object ID from name
|
|
355
|
+
#
|
|
356
|
+
# @param id [String] ID or NAME
|
|
357
|
+
# @param obj [OpenNebula::Class] OpenNebula pool class
|
|
358
|
+
#
|
|
359
|
+
# @return [Integer] Object ID
|
|
360
|
+
def get_obj_id(id, obj)
|
|
361
|
+
if (id.is_a? Integer) || id.match(/^\d+$/)
|
|
362
|
+
id.to_i
|
|
363
|
+
else
|
|
364
|
+
pool = obj.new(@client)
|
|
365
|
+
rc = pool.info_all
|
|
366
|
+
|
|
367
|
+
return rc if OpenNebula.is_error?(rc)
|
|
368
|
+
|
|
369
|
+
rc = pool.find {|v| v['NAME'] == id }
|
|
370
|
+
|
|
371
|
+
return Error.new("Object `#{id}` not found") unless rc
|
|
372
|
+
|
|
373
|
+
rc['ID'].to_i
|
|
374
|
+
end
|
|
375
|
+
end
|
|
376
|
+
|
|
126
377
|
private
|
|
127
378
|
|
|
128
|
-
def factory(id=nil)
|
|
379
|
+
def factory(id = nil)
|
|
129
380
|
if id
|
|
130
381
|
OpenNebula::MarketPlaceApp.new_with_id(id, @client)
|
|
131
382
|
else
|
|
@@ -134,91 +385,244 @@ class OneMarketPlaceAppHelper < OpenNebulaHelper::OneHelper
|
|
|
134
385
|
end
|
|
135
386
|
end
|
|
136
387
|
|
|
137
|
-
def factory_pool(user_flag
|
|
388
|
+
def factory_pool(user_flag = -2)
|
|
138
389
|
OpenNebula::MarketPlaceAppPool.new(@client, user_flag)
|
|
139
390
|
end
|
|
140
391
|
|
|
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
|
|
392
|
+
def format_resource(app, _options = {})
|
|
393
|
+
str='%-15s: %-20s'
|
|
394
|
+
str_h1='%-80s'
|
|
395
|
+
|
|
396
|
+
CLIHelper.print_header(
|
|
397
|
+
str_h1 % "MARKETPLACE APP #{app['ID']} INFORMATION"
|
|
398
|
+
)
|
|
399
|
+
puts format(str, 'ID', app.id.to_s)
|
|
400
|
+
puts format(str, 'NAME', app.name)
|
|
401
|
+
puts format(str, 'TYPE', app.type_str)
|
|
402
|
+
puts format(str, 'USER', app['UNAME'])
|
|
403
|
+
puts format(str, 'GROUP', app['GNAME'])
|
|
404
|
+
puts format(str, 'MARKETPLACE', app['MARKETPLACE'])
|
|
405
|
+
puts format(str,
|
|
406
|
+
'STATE',
|
|
407
|
+
OneMarketPlaceAppHelper.state_to_str(app['STATE']))
|
|
408
|
+
puts format(str,
|
|
409
|
+
'LOCK',
|
|
410
|
+
OpenNebulaHelper.level_lock_to_str(app['LOCK/LOCKED']))
|
|
154
411
|
|
|
155
412
|
puts
|
|
156
413
|
|
|
157
|
-
CLIHelper.print_header(str_h1 %
|
|
414
|
+
CLIHelper.print_header(str_h1 % 'PERMISSIONS', false)
|
|
158
415
|
|
|
159
|
-
[
|
|
160
|
-
mask =
|
|
161
|
-
mask[0] =
|
|
162
|
-
mask[1] =
|
|
163
|
-
mask[2] =
|
|
416
|
+
%w[OWNER GROUP OTHER].each do |e|
|
|
417
|
+
mask = '---'
|
|
418
|
+
mask[0] = 'u' if app["PERMISSIONS/#{e}_U"] == '1'
|
|
419
|
+
mask[1] = 'm' if app["PERMISSIONS/#{e}_M"] == '1'
|
|
420
|
+
mask[2] = 'a' if app["PERMISSIONS/#{e}_A"] == '1'
|
|
164
421
|
|
|
165
|
-
puts str
|
|
166
|
-
|
|
422
|
+
puts format(str, e, mask)
|
|
423
|
+
end
|
|
167
424
|
puts
|
|
168
425
|
|
|
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
|
|
426
|
+
CLIHelper.print_header(str_h1 % 'DETAILS', false)
|
|
427
|
+
|
|
428
|
+
puts format(str, 'SOURCE', app['SOURCE'])
|
|
429
|
+
puts format(str, 'MD5', app['MD5'])
|
|
430
|
+
puts format(str, 'PUBLISHER', app['PUBLISHER'])
|
|
431
|
+
puts format(str,
|
|
432
|
+
'REGISTER TIME',
|
|
433
|
+
Time.at(app['REGTIME'].to_i).strftime('%c'))
|
|
434
|
+
puts format(str, 'VERSION', app['VERSION'])
|
|
435
|
+
puts format(str, 'DESCRIPTION', app['DESCRIPTION'])
|
|
436
|
+
puts format(str,
|
|
437
|
+
'SIZE',
|
|
438
|
+
OpenNebulaHelper.unit_to_str(app['SIZE'].to_i, {}, 'M'))
|
|
439
|
+
puts format(str, 'ORIGIN_ID', app['ORIGIN_ID'])
|
|
440
|
+
puts format(str, 'FORMAT', app['FORMAT'])
|
|
180
441
|
|
|
181
442
|
puts
|
|
182
443
|
|
|
183
|
-
CLIHelper.print_header(str_h1 %
|
|
444
|
+
CLIHelper.print_header(str_h1 % 'IMPORT TEMPLATE', false)
|
|
184
445
|
|
|
185
446
|
puts Base64.decode64(app['APPTEMPLATE64'])
|
|
186
447
|
|
|
187
448
|
puts
|
|
188
449
|
|
|
189
|
-
CLIHelper.print_header(str_h1 %
|
|
450
|
+
CLIHelper.print_header(str_h1 % 'MARKETPLACE APP TEMPLATE', false)
|
|
190
451
|
puts app.template_str
|
|
191
452
|
|
|
192
453
|
puts
|
|
193
454
|
end
|
|
194
455
|
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
456
|
+
class << self
|
|
457
|
+
|
|
458
|
+
def create_variables(options, name)
|
|
459
|
+
names = [name].flatten
|
|
460
|
+
t = ''
|
|
461
|
+
|
|
462
|
+
names.each do |n|
|
|
463
|
+
next unless options[n]
|
|
464
|
+
|
|
465
|
+
t << "#{n.to_s.upcase}=\"#{options[n]}\"\n"
|
|
466
|
+
end
|
|
467
|
+
|
|
468
|
+
t
|
|
200
469
|
end
|
|
201
470
|
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
t<<"#{n.to_s.upcase}=\"#{options[n]}\"\n"
|
|
471
|
+
def create_datastore_template(options)
|
|
472
|
+
template_options = TEMPLATE_OPTIONS.map do |o|
|
|
473
|
+
o[:name].to_sym
|
|
206
474
|
end
|
|
475
|
+
|
|
476
|
+
template = create_variables(options,
|
|
477
|
+
template_options-[:dry, :image])
|
|
478
|
+
|
|
479
|
+
template << "ORIGIN_ID=#{options[:image]}\n" if options[:image]
|
|
480
|
+
template << "TYPE=image\n"
|
|
481
|
+
|
|
482
|
+
[0, template]
|
|
483
|
+
end
|
|
484
|
+
|
|
485
|
+
# Check if marketplace exists
|
|
486
|
+
#
|
|
487
|
+
# @param pool [MarketPlacePool] Marketplaces pool
|
|
488
|
+
# @param market [String] ID to check
|
|
489
|
+
#
|
|
490
|
+
# @return [Boolean] True if exists, false otherwise
|
|
491
|
+
def market_exist?(pool, market)
|
|
492
|
+
!pool.select {|v| v['ID'].to_i == market }.empty?
|
|
207
493
|
end
|
|
208
494
|
|
|
209
|
-
t
|
|
210
495
|
end
|
|
211
496
|
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
497
|
+
# Get private marketplace to import templates
|
|
498
|
+
#
|
|
499
|
+
# @return [OpenNebula::Pool] Marketplace pool or error if any
|
|
500
|
+
def private_markets
|
|
501
|
+
pool = MarketPlacePool.new(@client)
|
|
502
|
+
rc = pool.info
|
|
503
|
+
|
|
504
|
+
return rc if OpenNebula.is_error?(rc)
|
|
505
|
+
|
|
506
|
+
# Get private marketplaces
|
|
507
|
+
pool = pool.select {|market| MARKETS.include?(market['MARKET_MAD']) }
|
|
508
|
+
pool = pool.sort_by {|market| market['ID'].to_i }
|
|
509
|
+
|
|
510
|
+
if pool.empty?
|
|
511
|
+
return Error.new("There are no #{MARKETS.join('/')} marketplaces")
|
|
215
512
|
end
|
|
216
513
|
|
|
217
|
-
|
|
514
|
+
pool
|
|
515
|
+
end
|
|
516
|
+
|
|
517
|
+
# Get roles information when importing a service template into marketplace
|
|
518
|
+
#
|
|
519
|
+
# @param import_all [Boolean] true to import VM templates too
|
|
520
|
+
# @param body [Hash] Sevice Template information
|
|
521
|
+
# @param pool [Array] Marketplace pool
|
|
522
|
+
# @param market [Integer] Marketplace to import
|
|
523
|
+
#
|
|
524
|
+
# @return [Hash] Roles templates and marketplaces to import them
|
|
525
|
+
def import_service_template_roles(import_all, body, pool, market)
|
|
526
|
+
# Templates import information
|
|
527
|
+
#
|
|
528
|
+
# template_id => :market => marketplace ID to import it
|
|
529
|
+
# :template => ONE Template information
|
|
530
|
+
# :name => generated name for the template
|
|
531
|
+
markets = {}
|
|
532
|
+
default_mp = pool.first['ID'].to_i
|
|
533
|
+
|
|
534
|
+
if import_all
|
|
535
|
+
# Read marketplace where import each different VM template
|
|
536
|
+
# It can only be a private marketplace
|
|
537
|
+
unless market
|
|
538
|
+
puts
|
|
539
|
+
puts 'Available Marketplaces for roles (please enter ID)'
|
|
540
|
+
pool.each do |m|
|
|
541
|
+
puts "- #{m['ID']}: #{m['NAME']}"
|
|
542
|
+
end
|
|
543
|
+
puts
|
|
544
|
+
end
|
|
545
|
+
|
|
546
|
+
# Iterate all the roles to ask for the marketplace
|
|
547
|
+
body['roles'].each do |role|
|
|
548
|
+
# Read role VM template information from OpenNebula
|
|
549
|
+
template = Template.new_with_id(role['vm_template'], @client)
|
|
550
|
+
rc = template.info
|
|
551
|
+
|
|
552
|
+
return rc if OpenNebula.is_error?(rc)
|
|
553
|
+
|
|
554
|
+
next if markets.include?(template['ID'])
|
|
555
|
+
|
|
556
|
+
if market
|
|
557
|
+
m = market
|
|
558
|
+
else
|
|
559
|
+
# Keep asking while user selects an incorrect marketplace
|
|
560
|
+
until OneMarketPlaceAppHelper.market_exist?(pool, m)
|
|
561
|
+
print 'Where do you want to import' \
|
|
562
|
+
"`#{template['NAME']}`? (default=#{default_mp})"
|
|
563
|
+
m = STDIN.readline.chop
|
|
564
|
+
|
|
565
|
+
if m.empty?
|
|
566
|
+
puts default_mp
|
|
567
|
+
m = default_mp
|
|
568
|
+
else
|
|
569
|
+
m = m.to_i
|
|
570
|
+
end
|
|
571
|
+
end
|
|
572
|
+
end
|
|
573
|
+
|
|
574
|
+
# Update current template information
|
|
575
|
+
markets[template['ID']] = {}
|
|
576
|
+
markets[template['ID']][:market] = m
|
|
577
|
+
markets[template['ID']][:template] = template
|
|
578
|
+
end
|
|
579
|
+
else
|
|
580
|
+
# Do not ask for marketplaces, just fill templates information
|
|
581
|
+
body['roles'].each do |role|
|
|
582
|
+
# Read role VM template information from OpenNebula
|
|
583
|
+
template = Template.new_with_id(role['vm_template'], @client)
|
|
584
|
+
rc = template.info
|
|
218
585
|
|
|
219
|
-
|
|
220
|
-
template << "TYPE=image\n"
|
|
586
|
+
return rc if OpenNebula.is_error?(rc)
|
|
221
587
|
|
|
222
|
-
|
|
588
|
+
next if markets.include?(template['ID'])
|
|
589
|
+
|
|
590
|
+
# update current template information
|
|
591
|
+
markets[template['id']] = {}
|
|
592
|
+
markets[template['id']][:template] = template
|
|
593
|
+
end
|
|
594
|
+
end
|
|
595
|
+
|
|
596
|
+
markets
|
|
597
|
+
end
|
|
598
|
+
|
|
599
|
+
# Create applications in Marketplace
|
|
600
|
+
#
|
|
601
|
+
# @param markets [Hash] Marketplaces and templates information
|
|
602
|
+
# @param import_all [Boolean] true to import images too
|
|
603
|
+
# @param template_name [String] Virtual Machine Template app name
|
|
604
|
+
#
|
|
605
|
+
# @return [String] Error message in case of any
|
|
606
|
+
def create_apps(markets, import_all, template_name = nil)
|
|
607
|
+
ids = nil
|
|
608
|
+
|
|
609
|
+
markets.each do |_, market|
|
|
610
|
+
template = market[:template]
|
|
611
|
+
|
|
612
|
+
template.extend(OpenNebula::TemplateExt)
|
|
613
|
+
|
|
614
|
+
rc, ids = template.mp_import(market[:market].to_i,
|
|
615
|
+
import_all,
|
|
616
|
+
template_name)
|
|
617
|
+
|
|
618
|
+
return [rc.message, ids] if OpenNebula.is_error?(rc)
|
|
619
|
+
|
|
620
|
+
# Store name to use it after
|
|
621
|
+
market[:name] = nil
|
|
622
|
+
market[:name] = rc
|
|
623
|
+
end
|
|
624
|
+
|
|
625
|
+
['', ids]
|
|
223
626
|
end
|
|
627
|
+
|
|
224
628
|
end
|