opennebula-cli 6.4.0 → 6.4.2
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/onedatastore +1 -1
- data/bin/oneflow +1 -1
- data/bin/oneflow-template +10 -12
- data/bin/onehost +1 -1
- data/bin/oneimage +6 -6
- data/bin/onelog +87 -12
- data/bin/onemarket +1 -1
- data/bin/onemarketapp +3 -3
- data/bin/onesecgroup +1 -1
- data/bin/onetemplate +44 -10
- data/bin/onevcenter +37 -2
- data/bin/onevm +23 -17
- data/bin/onevmgroup +1 -1
- data/bin/onevnet +3 -3
- data/bin/onevntemplate +41 -6
- data/bin/onevrouter +1 -1
- data/lib/one_helper/onevcenter_helper.rb +0 -55
- data/lib/one_helper/onevm_helper.rb +1 -1
- data/lib/one_helper.rb +51 -3
- data/share/schemas/xsd/host.xsd +2 -0
- metadata +4 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6e72258e445621b7bb43729bce0ef5f95f4a0debd990f3983bd8845fa19eebc0
|
4
|
+
data.tar.gz: 4776aa4b2f7e59f114dee073504b2029f37cbf99ca544be0924af26a3f969a5c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8293cbaf48c76f3601a0dd2d06b63aa3ff52bbbbb4c2fd510578224a4555cee0b0c9b6fae7486de1bc922d9cbc2a9844a4bac06e8b394ebea1b145dc6bae2718
|
7
|
+
data.tar.gz: e42b6fc85a88aa97ca9be7d1f464b048993ca443c9119121cae800018ef1f27a90899e2d0cbcd18e72ac142b7bd8aac2568bcf1997933e42388f7896f96bd289
|
data/bin/onedatastore
CHANGED
@@ -158,7 +158,7 @@ CommandParser::CmdParser.new(ARGV) do
|
|
158
158
|
|
159
159
|
command :chmod, chmod_desc, [:range, :datastoreid_list], :octet do
|
160
160
|
helper.perform_actions(args[0], options, 'Permissions changed') do |obj|
|
161
|
-
obj.chmod_octet(args[1])
|
161
|
+
obj.chmod_octet(OpenNebulaHelper.to_octet(args[1]))
|
162
162
|
end
|
163
163
|
end
|
164
164
|
|
data/bin/oneflow
CHANGED
@@ -285,7 +285,7 @@ CommandParser::CmdParser.new(ARGV) do
|
|
285
285
|
|
286
286
|
Service.perform_actions(args[0]) do |service_id|
|
287
287
|
params = {}
|
288
|
-
params['octet'] = args[1]
|
288
|
+
params['octet'] = OpenNebulaHelper.to_octet(args[1])
|
289
289
|
|
290
290
|
json = Service.build_json_action('chmod', params)
|
291
291
|
|
data/bin/oneflow-template
CHANGED
@@ -59,7 +59,6 @@ require 'tempfile'
|
|
59
59
|
|
60
60
|
require 'command_parser'
|
61
61
|
require 'opennebula/oneflow_client'
|
62
|
-
require 'models'
|
63
62
|
require 'cli_helper'
|
64
63
|
require 'one_helper/oneflowtemplate_helper'
|
65
64
|
|
@@ -235,26 +234,26 @@ CommandParser::CmdParser.new(ARGV) do
|
|
235
234
|
Instantiate a Service Template
|
236
235
|
EOT
|
237
236
|
|
238
|
-
command :instantiate,
|
239
|
-
instantiate_desc,
|
240
|
-
:templateid,
|
241
|
-
[:file, nil],
|
237
|
+
command :instantiate, instantiate_desc, :templateid, [:file, nil],
|
242
238
|
:options => [MULTIPLE, Service::JSON_FORMAT, Service::TOP] do
|
243
239
|
number = options[:multiple] || 1
|
244
240
|
params = {}
|
245
241
|
rc = 0
|
242
|
+
client = helper.client(options)
|
246
243
|
|
247
244
|
number.times do
|
248
245
|
params['merge_template'] = nil
|
249
246
|
params['merge_template'] = JSON.parse(File.read(args[1])) if args[1]
|
250
247
|
|
251
248
|
unless params['merge_template']
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
249
|
+
response = client.get("#{RESOURCE_PATH}/#{args[0]}")
|
250
|
+
|
251
|
+
if CloudClient.is_error?(response)
|
252
|
+
rc = [response.code.to_i, response.to_s]
|
253
|
+
break
|
254
|
+
end
|
256
255
|
|
257
|
-
body = JSON.parse(
|
256
|
+
body = JSON.parse(response.body)['DOCUMENT']['TEMPLATE']['BODY']
|
258
257
|
|
259
258
|
params['merge_template'] = helper.custom_attrs(
|
260
259
|
body['custom_attrs']
|
@@ -267,7 +266,6 @@ CommandParser::CmdParser.new(ARGV) do
|
|
267
266
|
end
|
268
267
|
|
269
268
|
json = Service.build_json_action('instantiate', params)
|
270
|
-
client = helper.client(options)
|
271
269
|
response = client.post("#{RESOURCE_PATH}/#{args[0]}/action", json)
|
272
270
|
|
273
271
|
if CloudClient.is_error?(response)
|
@@ -346,7 +344,7 @@ CommandParser::CmdParser.new(ARGV) do
|
|
346
344
|
|
347
345
|
Service.perform_actions(args[0]) do |service_id|
|
348
346
|
params = {}
|
349
|
-
params['octet'] = args[1]
|
347
|
+
params['octet'] = OpenNebulaHelper.to_octet(args[1])
|
350
348
|
|
351
349
|
json = Service.build_json_action('chmod', params)
|
352
350
|
|
data/bin/onehost
CHANGED
@@ -339,7 +339,7 @@ CommandParser::CmdParser.new(ARGV) do
|
|
339
339
|
rescue StandardError => e
|
340
340
|
STDERR.puts e
|
341
341
|
end
|
342
|
-
helper.perform_actions(args[0], options, '
|
342
|
+
helper.perform_actions(args[0], options, 'flushing') do |host|
|
343
343
|
host.flush action
|
344
344
|
end
|
345
345
|
end
|
data/bin/oneimage
CHANGED
@@ -234,7 +234,7 @@ CommandParser::CmdParser.new(ARGV) do
|
|
234
234
|
|
235
235
|
command :clone, clone_desc, :imageid, :name,
|
236
236
|
:options => [OneDatastoreHelper::DATASTORE] do
|
237
|
-
helper.perform_action(args[0], options, '
|
237
|
+
helper.perform_action(args[0], options, 'cloning') do |image|
|
238
238
|
ds_id = options[:datastore] || -1 # -1 clones to self
|
239
239
|
res = image.clone(args[1], ds_id)
|
240
240
|
|
@@ -252,7 +252,7 @@ CommandParser::CmdParser.new(ARGV) do
|
|
252
252
|
EOT
|
253
253
|
|
254
254
|
command :delete, delete_desc, [:range, :imageid_list] do
|
255
|
-
helper.perform_actions(args[0], options, '
|
255
|
+
helper.perform_actions(args[0], options, 'deleting') do |image|
|
256
256
|
image.delete
|
257
257
|
end
|
258
258
|
end
|
@@ -363,7 +363,7 @@ CommandParser::CmdParser.new(ARGV) do
|
|
363
363
|
command :chmod, chmod_desc, [:range, :imageid_list], :octet do
|
364
364
|
helper.perform_actions(args[0], options,
|
365
365
|
'Permissions changed') do |image|
|
366
|
-
image.chmod_octet(args[1])
|
366
|
+
image.chmod_octet(OpenNebulaHelper.to_octet(args[1]))
|
367
367
|
end
|
368
368
|
end
|
369
369
|
|
@@ -382,7 +382,7 @@ CommandParser::CmdParser.new(ARGV) do
|
|
382
382
|
EOT
|
383
383
|
|
384
384
|
command :'snapshot-delete', snapshot_delete_desc, :imageid, :snapshot_id do
|
385
|
-
helper.perform_action(args[0], options, 'snapshot
|
385
|
+
helper.perform_action(args[0], options, 'deleting snapshot') do |o|
|
386
386
|
o.snapshot_delete(args[1].to_i)
|
387
387
|
end
|
388
388
|
end
|
@@ -392,7 +392,7 @@ CommandParser::CmdParser.new(ARGV) do
|
|
392
392
|
EOT
|
393
393
|
|
394
394
|
command :'snapshot-revert', snapshot_revert_desc, :imageid, :snapshot_id do
|
395
|
-
helper.perform_action(args[0], options, 'image state
|
395
|
+
helper.perform_action(args[0], options, 'reverting image state') do |o|
|
396
396
|
o.snapshot_revert(args[1].to_i)
|
397
397
|
end
|
398
398
|
end
|
@@ -405,7 +405,7 @@ CommandParser::CmdParser.new(ARGV) do
|
|
405
405
|
snapshot_flatten_desc,
|
406
406
|
:imageid,
|
407
407
|
:snapshot_id do
|
408
|
-
helper.perform_action(args[0], options, 'snapshot
|
408
|
+
helper.perform_action(args[0], options, 'flattening snapshot') do |o|
|
409
409
|
o.snapshot_flatten(args[1].to_i)
|
410
410
|
end
|
411
411
|
end
|
data/bin/onelog
CHANGED
@@ -20,10 +20,34 @@ ONE_LOCATION = ENV['ONE_LOCATION']
|
|
20
20
|
|
21
21
|
if !ONE_LOCATION
|
22
22
|
RUBY_LIB_LOCATION = '/usr/lib/one/ruby'
|
23
|
+
GEMS_LOCATION = '/usr/share/one/gems'
|
24
|
+
LOG_LOCATION = '/var/log/one'
|
23
25
|
else
|
24
26
|
RUBY_LIB_LOCATION = ONE_LOCATION + '/lib/ruby'
|
27
|
+
GEMS_LOCATION = ONE_LOCATION + '/share/gems'
|
28
|
+
LOG_LOCATION = ONE_LOCATION + '/var'
|
25
29
|
end
|
26
30
|
|
31
|
+
# %%RUBYGEMS_SETUP_BEGIN%%
|
32
|
+
if File.directory?(GEMS_LOCATION)
|
33
|
+
real_gems_path = File.realpath(GEMS_LOCATION)
|
34
|
+
if !defined?(Gem) || Gem.path != [real_gems_path]
|
35
|
+
$LOAD_PATH.reject! {|l| l =~ /vendor_ruby/ }
|
36
|
+
|
37
|
+
# Suppress warnings from Rubygems
|
38
|
+
# https://github.com/OpenNebula/one/issues/5379
|
39
|
+
begin
|
40
|
+
verb = $VERBOSE
|
41
|
+
$VERBOSE = nil
|
42
|
+
require 'rubygems'
|
43
|
+
Gem.use_paths(real_gems_path)
|
44
|
+
ensure
|
45
|
+
$VERBOSE = verb
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
# %%RUBYGEMS_SETUP_END%%
|
50
|
+
|
27
51
|
$LOAD_PATH << RUBY_LIB_LOCATION
|
28
52
|
$LOAD_PATH << RUBY_LIB_LOCATION + '/cli'
|
29
53
|
|
@@ -33,13 +57,13 @@ DEFAULT_PAGER = 'less'
|
|
33
57
|
# List of OpenNebula services and the logs files
|
34
58
|
SERVICES = {
|
35
59
|
'fireedge' => { :log => 'fireedge.log', :error => 'fireedge.error' },
|
36
|
-
'monitor' => 'monitor.log',
|
37
|
-
'novnc' => 'novnc.log',
|
38
|
-
'oned' => 'oned.log',
|
60
|
+
'monitor' => { :log => 'monitor.log' },
|
61
|
+
'novnc' => { :log => 'novnc.log' },
|
62
|
+
'oned' => { :log => 'oned.log' },
|
39
63
|
'onehem' => { :log => 'onehem.log', :error => 'onehem.error' },
|
40
|
-
'sched' => 'sched.log',
|
64
|
+
'sched' => { :log => 'sched.log' },
|
41
65
|
'sunstone' => { :log => 'sunstone.log', :error => 'sunstone.error' },
|
42
|
-
'vcenter' => 'vcenter_monitor.log'
|
66
|
+
'vcenter' => { :log => 'vcenter_monitor.log' }
|
43
67
|
}
|
44
68
|
|
45
69
|
require 'command_parser'
|
@@ -77,25 +101,76 @@ CommandParser::CmdParser.new(ARGV) do
|
|
77
101
|
EOT
|
78
102
|
|
79
103
|
command :get, get_desc, :service, :options => [TYPE, PAGER, PAGER_OPTS] do
|
80
|
-
|
104
|
+
logs = SERVICES[args[0]]
|
105
|
+
pager = options[:pager] || DEFAULT_PAGER
|
106
|
+
|
107
|
+
unless logs
|
81
108
|
STDERR.puts "Service '#{args[0]}' not found"
|
82
109
|
exit 1
|
83
110
|
end
|
84
111
|
|
85
|
-
if options[:type] && !
|
112
|
+
if options[:type] && !logs[options[:type].to_sym]
|
86
113
|
STDERR.puts "Log file type '#{options[:type]}' not found"
|
87
114
|
exit 1
|
88
115
|
end
|
89
116
|
|
90
|
-
|
91
|
-
|
117
|
+
options[:type].nil? ? f = logs[:log] : f = logs[options[:type].to_sym]
|
118
|
+
|
119
|
+
system("#{pager} #{options[:pager_opts]} #{LOG_LOCATION}/#{f}")
|
120
|
+
end
|
121
|
+
|
122
|
+
vm_desc = <<-EOT.unindent
|
123
|
+
Gets VM log
|
124
|
+
EOT
|
125
|
+
|
126
|
+
command :'get-vm', vm_desc, :id, :options => [PAGER, PAGER_OPTS] do
|
127
|
+
pager = options[:pager] || DEFAULT_PAGER
|
128
|
+
|
129
|
+
begin
|
130
|
+
Integer(args[0])
|
131
|
+
|
132
|
+
if !ONE_LOCATION
|
133
|
+
file = "#{LOG_LOCATION}/#{args[0]}.log"
|
134
|
+
else
|
135
|
+
file = "#{LOG_LOCATION}/vms/#{args[0]}/vm.log"
|
136
|
+
end
|
137
|
+
|
138
|
+
unless File.exist?(file)
|
139
|
+
STDERR.puts "No LOG file found for '#{args[0]}' VM"
|
140
|
+
exit 1
|
141
|
+
end
|
142
|
+
|
143
|
+
system("#{pager} #{options[:pager_opts]} #{file}")
|
144
|
+
rescue StandardError
|
145
|
+
STDERR.puts 'Only ID is supported'
|
146
|
+
exit 1
|
92
147
|
end
|
148
|
+
end
|
93
149
|
|
94
|
-
|
150
|
+
service_desc = <<-EOT.unindent
|
151
|
+
Gets Service log
|
152
|
+
EOT
|
153
|
+
|
154
|
+
command :'get-service',
|
155
|
+
service_desc,
|
156
|
+
:id,
|
157
|
+
:options => [PAGER, PAGER_OPTS] do
|
95
158
|
pager = options[:pager] || DEFAULT_PAGER
|
96
159
|
|
97
|
-
|
160
|
+
begin
|
161
|
+
Integer(args[0])
|
162
|
+
|
163
|
+
file = "#{LOG_LOCATION}/oneflow/#{args[0]}.log"
|
98
164
|
|
99
|
-
|
165
|
+
unless File.exist?(file)
|
166
|
+
STDERR.puts "No LOG file found for '#{args[0]}' service"
|
167
|
+
exit 1
|
168
|
+
end
|
169
|
+
|
170
|
+
system("#{pager} #{options[:pager_opts]} #{file}")
|
171
|
+
rescue StandardError
|
172
|
+
STDERR.puts 'Only ID is supported'
|
173
|
+
exit 1
|
174
|
+
end
|
100
175
|
end
|
101
176
|
end
|
data/bin/onemarket
CHANGED
@@ -151,7 +151,7 @@ CommandParser::CmdParser.new(ARGV) do
|
|
151
151
|
|
152
152
|
command :chmod, chmod_desc, [:range, :marketplaceid_list], :octet do
|
153
153
|
helper.perform_actions(args[0], options, 'Permissions changed') do |obj|
|
154
|
-
obj.chmod_octet(args[1])
|
154
|
+
obj.chmod_octet(OpenNebulaHelper.to_octet(args[1]))
|
155
155
|
end
|
156
156
|
end
|
157
157
|
|
data/bin/onemarketapp
CHANGED
@@ -284,7 +284,7 @@ CommandParser::CmdParser.new(ARGV) do
|
|
284
284
|
EOT
|
285
285
|
|
286
286
|
command :export, export_desc, :appid, :name, :options => EXPORT_OPTIONS do
|
287
|
-
helper.perform_action(args[0], options, '
|
287
|
+
helper.perform_action(args[0], options, 'exporting') do |obj|
|
288
288
|
tag ="tag=#{options[:tag]}" if options[:tag]
|
289
289
|
|
290
290
|
obj.extend(MarketPlaceAppExt)
|
@@ -325,7 +325,7 @@ CommandParser::CmdParser.new(ARGV) do
|
|
325
325
|
|
326
326
|
command :download, download_desc, :appid, :path,
|
327
327
|
:options => [OpenNebulaHelper::FORCE] do
|
328
|
-
helper.perform_action(args[0], options, '
|
328
|
+
helper.perform_action(args[0], options, 'downloading') do
|
329
329
|
download_args = [:marketplaceapp, args[0], args[1], options[:force]]
|
330
330
|
OpenNebulaHelper.download_resource_sunstone(*download_args)
|
331
331
|
end
|
@@ -388,7 +388,7 @@ CommandParser::CmdParser.new(ARGV) do
|
|
388
388
|
|
389
389
|
command :chmod, chmod_desc, [:range, :appid_list], :octet do
|
390
390
|
helper.perform_actions(args[0], options, 'Permissions changed') do |app|
|
391
|
-
app.chmod_octet(args[1])
|
391
|
+
app.chmod_octet(OpenNebulaHelper.to_octet(args[1]))
|
392
392
|
end
|
393
393
|
end
|
394
394
|
|
data/bin/onesecgroup
CHANGED
@@ -174,7 +174,7 @@ CommandParser::CmdParser.new(ARGV) do
|
|
174
174
|
|
175
175
|
command :chmod, chmod_desc, [:range, :secgroupid_list], :octet do
|
176
176
|
helper.perform_actions(args[0], options, 'Permissions changed') do |t|
|
177
|
-
t.chmod_octet(args[1])
|
177
|
+
t.chmod_octet(OpenNebulaHelper.to_octet(args[1]))
|
178
178
|
end
|
179
179
|
end
|
180
180
|
|
data/bin/onetemplate
CHANGED
@@ -87,6 +87,14 @@ CommandParser::CmdParser.new(ARGV) do
|
|
87
87
|
:description => 'lock all actions'
|
88
88
|
}
|
89
89
|
|
90
|
+
PREFIX = {
|
91
|
+
:name => 'prefix',
|
92
|
+
:large => '--prefix prefix',
|
93
|
+
:description => 'Prefix to autogenerate name, e.g: 001, 01',
|
94
|
+
:format => String
|
95
|
+
|
96
|
+
}
|
97
|
+
|
90
98
|
########################################################################
|
91
99
|
# Global Options
|
92
100
|
########################################################################
|
@@ -102,7 +110,8 @@ CommandParser::CmdParser.new(ARGV) do
|
|
102
110
|
OneTemplateHelper::MULTIPLE,
|
103
111
|
OneTemplateHelper::USERDATA,
|
104
112
|
OneVMHelper::HOLD,
|
105
|
-
OneTemplateHelper::PERSISTENT
|
113
|
+
OneTemplateHelper::PERSISTENT,
|
114
|
+
PREFIX
|
106
115
|
]
|
107
116
|
|
108
117
|
########################################################################
|
@@ -252,16 +261,37 @@ CommandParser::CmdParser.new(ARGV) do
|
|
252
261
|
number = options[:multiple] || 1
|
253
262
|
user_inputs = options[:user_inputs]
|
254
263
|
|
255
|
-
number.times do |i|
|
256
|
-
exit_code = helper.perform_action(
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
264
|
+
number.times.each_with_index do |i, index|
|
265
|
+
exit_code = helper.perform_action(
|
266
|
+
args[0],
|
267
|
+
options,
|
268
|
+
'instantiated'
|
269
|
+
) do |t|
|
270
|
+
name = options[:name]
|
271
|
+
prefix = options[:prefix]
|
272
|
+
c_i = nil
|
273
|
+
p = nil
|
274
|
+
|
275
|
+
if prefix && name
|
276
|
+
# Get leading zeros
|
277
|
+
p = prefix.scan(/^0+/)[0]
|
278
|
+
|
279
|
+
# Get current index
|
280
|
+
c_i = prefix.gsub(p, '') if p
|
281
|
+
|
282
|
+
# Convert it to Integer to check if we can use it
|
283
|
+
begin
|
284
|
+
c_i = Integer(c_i)
|
285
|
+
name = name.gsub('%i', "#{p}#{c_i + index}")
|
286
|
+
rescue StandardError
|
287
|
+
end
|
288
|
+
elsif name
|
289
|
+
name = name.gsub('%i', i.to_s)
|
290
|
+
end
|
262
291
|
|
292
|
+
on_hold = !options[:hold].nil?
|
263
293
|
extra_template = ''
|
264
|
-
rc
|
294
|
+
rc = t.info
|
265
295
|
|
266
296
|
if OpenNebula.is_error?(rc)
|
267
297
|
STDERR.puts rc.message
|
@@ -281,6 +311,10 @@ CommandParser::CmdParser.new(ARGV) do
|
|
281
311
|
extra_template = res.last
|
282
312
|
end
|
283
313
|
|
314
|
+
if c_i
|
315
|
+
extra_template.gsub!('%i', "#{p}#{c_i + index}")
|
316
|
+
end
|
317
|
+
|
284
318
|
if !user_inputs
|
285
319
|
user_inputs = OneTemplateHelper.get_user_inputs(t.to_hash)
|
286
320
|
else
|
@@ -344,7 +378,7 @@ CommandParser::CmdParser.new(ARGV) do
|
|
344
378
|
recursive = (options[:recursive] == true)
|
345
379
|
|
346
380
|
helper.perform_actions(args[0], options, 'Permissions changed') do |t|
|
347
|
-
t.chmod_octet(args[1], recursive)
|
381
|
+
t.chmod_octet(OpenNebulaHelper.to_octet(args[1]), recursive)
|
348
382
|
end
|
349
383
|
end
|
350
384
|
|
data/bin/onevcenter
CHANGED
@@ -409,7 +409,42 @@ CommandParser::CmdParser.new(ARGV) do
|
|
409
409
|
|
410
410
|
begin
|
411
411
|
print '.'
|
412
|
-
|
412
|
+
|
413
|
+
client = Client.new
|
414
|
+
|
415
|
+
vm_pool = VirtualMachinePool.new(client, -1)
|
416
|
+
host_pool = HostPool.new(client)
|
417
|
+
deploy_id = -1
|
418
|
+
host_id = -1
|
419
|
+
hostname = ''
|
420
|
+
|
421
|
+
rc = vm_pool.info
|
422
|
+
raise rc.message if OpenNebula.is_error?(rc)
|
423
|
+
|
424
|
+
rc = host_pool.info
|
425
|
+
raise rc.message if OpenNebula.is_error?(rc)
|
426
|
+
|
427
|
+
vm_pool.each do |vm|
|
428
|
+
next if vm.id.to_s != vmid
|
429
|
+
|
430
|
+
deploy_id = vm.deploy_id
|
431
|
+
vm_history = vm.to_hash['VM']['HISTORY_RECORDS']['HISTORY']
|
432
|
+
hostname = vm_history['HOSTNAME']
|
433
|
+
break
|
434
|
+
end
|
435
|
+
|
436
|
+
host_pool.each do |host|
|
437
|
+
if host.name == hostname
|
438
|
+
host_id = host.id
|
439
|
+
end
|
440
|
+
end
|
441
|
+
|
442
|
+
vi_client = VCenterDriver::VIClient.new_from_host(host_id)
|
443
|
+
vm = VCenterDriver::VirtualMachine
|
444
|
+
.new(vi_client, deploy_id, vmid)
|
445
|
+
|
446
|
+
keys = vm.extra_config_keys
|
447
|
+
|
413
448
|
print '.'
|
414
449
|
|
415
450
|
if keys.empty?
|
@@ -422,7 +457,7 @@ CommandParser::CmdParser.new(ARGV) do
|
|
422
457
|
puts 'The following keys will be removed:'
|
423
458
|
keys.each {|key| puts "\t- #{key}" }
|
424
459
|
|
425
|
-
|
460
|
+
vm.clear_tags
|
426
461
|
rescue StandardError => e
|
427
462
|
STDERR.puts "Couldn't clear VM tags. Reason: #{e.message}"
|
428
463
|
exit 1
|
data/bin/onevm
CHANGED
@@ -472,7 +472,13 @@ CommandParser::CmdParser.new(ARGV) do
|
|
472
472
|
verbose = "disk #{disk_id} prepared to be saved in " \
|
473
473
|
"the image #{image_name}"
|
474
474
|
else
|
475
|
-
snapshot_id =
|
475
|
+
err, snapshot_id = helper.retrieve_disk_snapshot_id(args[0],
|
476
|
+
snapshot_id)
|
477
|
+
|
478
|
+
if err == -1
|
479
|
+
STDERR.puts snapshot_id
|
480
|
+
exit(-1)
|
481
|
+
end
|
476
482
|
|
477
483
|
verbose = "disk #{disk_id} snapshot #{snapshot_id} prepared to " \
|
478
484
|
"be saved in the image #{image_name}"
|
@@ -511,7 +517,7 @@ CommandParser::CmdParser.new(ARGV) do
|
|
511
517
|
if !options[:schedule].nil?
|
512
518
|
helper.schedule_actions(args[0], options, command_name)
|
513
519
|
else
|
514
|
-
helper.perform_actions(args[0], options, '
|
520
|
+
helper.perform_actions(args[0], options, 'terminating') do |vm|
|
515
521
|
vm.terminate(options[:hard] == true)
|
516
522
|
end
|
517
523
|
end
|
@@ -827,7 +833,7 @@ CommandParser::CmdParser.new(ARGV) do
|
|
827
833
|
template << ' ]'
|
828
834
|
end
|
829
835
|
|
830
|
-
helper.perform_action(args[0], options, '
|
836
|
+
helper.perform_action(args[0], options, 'Attaching disk') do |vm|
|
831
837
|
vm.disk_attach(template)
|
832
838
|
end
|
833
839
|
end
|
@@ -841,7 +847,7 @@ CommandParser::CmdParser.new(ARGV) do
|
|
841
847
|
command :"disk-detach", disk_detach_desc, :vmid, :diskid do
|
842
848
|
diskid = args[1].to_i
|
843
849
|
|
844
|
-
helper.perform_action(args[0], options, '
|
850
|
+
helper.perform_action(args[0], options, 'Detaching disk') do |vm|
|
845
851
|
vm.disk_detach(diskid)
|
846
852
|
end
|
847
853
|
end
|
@@ -904,7 +910,7 @@ CommandParser::CmdParser.new(ARGV) do
|
|
904
910
|
end
|
905
911
|
end
|
906
912
|
|
907
|
-
helper.perform_action(args[0], options, '
|
913
|
+
helper.perform_action(args[0], options, 'Attaching NIC') do |vm|
|
908
914
|
vm.nic_attach(template)
|
909
915
|
end
|
910
916
|
end
|
@@ -918,7 +924,7 @@ CommandParser::CmdParser.new(ARGV) do
|
|
918
924
|
command :"nic-detach", nic_detach_desc, :vmid, :nicid do
|
919
925
|
nicid = args[1].to_i
|
920
926
|
|
921
|
-
helper.perform_action(args[0], options, '
|
927
|
+
helper.perform_action(args[0], options, 'Detaching NIC') do |vm|
|
922
928
|
vm.nic_detach(nicid)
|
923
929
|
end
|
924
930
|
end
|
@@ -933,7 +939,7 @@ CommandParser::CmdParser.new(ARGV) do
|
|
933
939
|
nic_id = args[1].to_i
|
934
940
|
sg_id = args[2].to_i
|
935
941
|
|
936
|
-
helper.perform_action(args[0], options, '
|
942
|
+
helper.perform_action(args[0], options, 'Attaching SG') do |vm|
|
937
943
|
vm.sg_attach(nic_id, sg_id)
|
938
944
|
end
|
939
945
|
end
|
@@ -948,7 +954,7 @@ CommandParser::CmdParser.new(ARGV) do
|
|
948
954
|
nic_id = args[1].to_i
|
949
955
|
sg_id = args[2].to_i
|
950
956
|
|
951
|
-
helper.perform_action(args[0], options, '
|
957
|
+
helper.perform_action(args[0], options, 'Detaching SG') do |vm|
|
952
958
|
vm.sg_detach(nic_id, sg_id)
|
953
959
|
end
|
954
960
|
end
|
@@ -981,7 +987,7 @@ CommandParser::CmdParser.new(ARGV) do
|
|
981
987
|
|
982
988
|
command :chmod, chmod_desc, [:range, :vmid_list], :octet do
|
983
989
|
helper.perform_actions(args[0], options, 'Permissions changed') do |vm|
|
984
|
-
vm.chmod_octet(args[1])
|
990
|
+
vm.chmod_octet(OpenNebulaHelper.to_octet(args[1]))
|
985
991
|
end
|
986
992
|
end
|
987
993
|
|
@@ -1041,7 +1047,7 @@ CommandParser::CmdParser.new(ARGV) do
|
|
1041
1047
|
|
1042
1048
|
helper.schedule_actions(args[0], options, @comm_name)
|
1043
1049
|
else
|
1044
|
-
helper.perform_actions(args[0], options, 'snapshot
|
1050
|
+
helper.perform_actions(args[0], options, 'creating snapshot') do |o|
|
1045
1051
|
o.snapshot_create(args[1])
|
1046
1052
|
end
|
1047
1053
|
end
|
@@ -1065,7 +1071,7 @@ CommandParser::CmdParser.new(ARGV) do
|
|
1065
1071
|
|
1066
1072
|
helper.schedule_actions([args[0]], options, @comm_name)
|
1067
1073
|
else
|
1068
|
-
helper.perform_action(args[0], options, 'snapshot
|
1074
|
+
helper.perform_action(args[0], options, 'reverting snapshot') do |o|
|
1069
1075
|
o.snapshot_revert(args[1].to_i)
|
1070
1076
|
end
|
1071
1077
|
end
|
@@ -1089,7 +1095,7 @@ CommandParser::CmdParser.new(ARGV) do
|
|
1089
1095
|
|
1090
1096
|
helper.schedule_actions([args[0]], options, @comm_name)
|
1091
1097
|
else
|
1092
|
-
helper.perform_action(args[0], options, 'snapshot
|
1098
|
+
helper.perform_action(args[0], options, 'deleting snapshot') do |o|
|
1093
1099
|
o.snapshot_delete(args[1])
|
1094
1100
|
end
|
1095
1101
|
end
|
@@ -1117,7 +1123,7 @@ CommandParser::CmdParser.new(ARGV) do
|
|
1117
1123
|
helper.schedule_actions([args[0]], options, @comm_name)
|
1118
1124
|
else
|
1119
1125
|
helper.perform_action(args[0], options,
|
1120
|
-
'disk snapshot
|
1126
|
+
'creating disk snapshot') do |o|
|
1121
1127
|
o.disk_snapshot_create(args[1].to_i, args[2])
|
1122
1128
|
end
|
1123
1129
|
end
|
@@ -1144,7 +1150,7 @@ CommandParser::CmdParser.new(ARGV) do
|
|
1144
1150
|
helper.schedule_actions([args[0]], options, @comm_name)
|
1145
1151
|
else
|
1146
1152
|
helper.perform_action(args[0], options,
|
1147
|
-
'disk snapshot
|
1153
|
+
'reverting disk snapshot') do |o|
|
1148
1154
|
o.disk_snapshot_revert(args[1].to_i, args[2].to_i)
|
1149
1155
|
end
|
1150
1156
|
end
|
@@ -1171,7 +1177,7 @@ CommandParser::CmdParser.new(ARGV) do
|
|
1171
1177
|
helper.schedule_actions([args[0]], options, @comm_name)
|
1172
1178
|
else
|
1173
1179
|
helper.perform_action(args[0], options,
|
1174
|
-
'disk snapshot
|
1180
|
+
'deleting disk snapshot') do |o|
|
1175
1181
|
o.disk_snapshot_delete(args[1].to_i, args[2].to_i)
|
1176
1182
|
end
|
1177
1183
|
end
|
@@ -1207,7 +1213,7 @@ CommandParser::CmdParser.new(ARGV) do
|
|
1207
1213
|
|
1208
1214
|
command :"disk-resize", disk_resize_desc,
|
1209
1215
|
:vmid, :diskid, :size do
|
1210
|
-
helper.perform_action(args[0], options, 'disk
|
1216
|
+
helper.perform_action(args[0], options, 'resizing disk') do |o|
|
1211
1217
|
o.info
|
1212
1218
|
size = o["/VM/TEMPLATE/DISK[DISK_ID='#{args[1]}']/SIZE"].to_i
|
1213
1219
|
|
@@ -1344,7 +1350,7 @@ CommandParser::CmdParser.new(ARGV) do
|
|
1344
1350
|
FEATURES = ["ACPI", "PAE", "APIC", "LOCALTIME", "HYPERV", "GUEST_AGENT", "IOTHREADS"]
|
1345
1351
|
INPUT = ["TYPE", "BUS"]
|
1346
1352
|
GRAPHICS = ["TYPE", "LISTEN", "PASSWD", "KEYMAP" ]
|
1347
|
-
RAW = ["DATA", "DATA_VMX", "TYPE"]
|
1353
|
+
RAW = ["DATA", "DATA_VMX", "TYPE", "VALIDATE"]
|
1348
1354
|
CPU_MODEL = ["MODEL"]
|
1349
1355
|
CONTEXT (any value, **variable substitution will be made**)
|
1350
1356
|
EOT
|
data/bin/onevmgroup
CHANGED
@@ -197,7 +197,7 @@ CommandParser::CmdParser.new(ARGV) do
|
|
197
197
|
|
198
198
|
command :chmod, chmod_desc, [:range, :vmgroupid_list], :octet do
|
199
199
|
helper.perform_actions(args[0], options, 'Permissions changed') do |t|
|
200
|
-
t.chmod_octet(args[1])
|
200
|
+
t.chmod_octet(OpenNebulaHelper.to_octet(args[1]))
|
201
201
|
end
|
202
202
|
end
|
203
203
|
|
data/bin/onevnet
CHANGED
@@ -176,7 +176,7 @@ CommandParser::CmdParser.new(ARGV) do
|
|
176
176
|
EOT
|
177
177
|
|
178
178
|
command :delete, delete_desc, [:range, :vnetid_list] do
|
179
|
-
helper.perform_actions(args[0], options, '
|
179
|
+
helper.perform_actions(args[0], options, 'deleting') do |vn|
|
180
180
|
vn.delete
|
181
181
|
end
|
182
182
|
end
|
@@ -187,7 +187,7 @@ CommandParser::CmdParser.new(ARGV) do
|
|
187
187
|
|
188
188
|
command :addar, addar_desc, :vnetid, [:file, nil],
|
189
189
|
:options => STD_OPTIONS + OneVNetHelper::ADDAR_OPTIONS do
|
190
|
-
helper.perform_action(args[0], options, '
|
190
|
+
helper.perform_action(args[0], options, 'address range added') do |vn|
|
191
191
|
if args[1]
|
192
192
|
ar = File.read(args[1])
|
193
193
|
else
|
@@ -335,7 +335,7 @@ CommandParser::CmdParser.new(ARGV) do
|
|
335
335
|
|
336
336
|
command :chmod, chmod_desc, [:range, :vnetid_list], :octet do
|
337
337
|
helper.perform_actions(args[0], options, 'Permissions changed') do |vn|
|
338
|
-
vn.chmod_octet(args[1])
|
338
|
+
vn.chmod_octet(OpenNebulaHelper.to_octet(args[1]))
|
339
339
|
end
|
340
340
|
end
|
341
341
|
|
data/bin/onevntemplate
CHANGED
@@ -87,6 +87,14 @@ CommandParser::CmdParser.new(ARGV) do
|
|
87
87
|
:description => 'lock all actions'
|
88
88
|
}
|
89
89
|
|
90
|
+
PREFIX = {
|
91
|
+
:name => 'prefix',
|
92
|
+
:large => '--prefix prefix',
|
93
|
+
:description => 'Prefix to autogenerate name, e.g: 001, 01',
|
94
|
+
:format => String
|
95
|
+
|
96
|
+
}
|
97
|
+
|
90
98
|
########################################################################
|
91
99
|
# Global Options
|
92
100
|
########################################################################
|
@@ -102,7 +110,8 @@ CommandParser::CmdParser.new(ARGV) do
|
|
102
110
|
OneVNTemplateHelper::MULTIPLE,
|
103
111
|
OneVNTemplateHelper::EXTENDED,
|
104
112
|
OpenNebulaHelper::AS_USER,
|
105
|
-
OpenNebulaHelper::AS_GROUP
|
113
|
+
OpenNebulaHelper::AS_GROUP,
|
114
|
+
PREFIX
|
106
115
|
]
|
107
116
|
|
108
117
|
########################################################################
|
@@ -204,10 +213,32 @@ CommandParser::CmdParser.new(ARGV) do
|
|
204
213
|
number = options[:multiple] || 1
|
205
214
|
|
206
215
|
number.times do |i|
|
207
|
-
exit_code = helper.perform_action(
|
208
|
-
|
209
|
-
|
210
|
-
|
216
|
+
exit_code = helper.perform_action(
|
217
|
+
args[0],
|
218
|
+
options,
|
219
|
+
'instantiated'
|
220
|
+
) do |t|
|
221
|
+
name = options[:name]
|
222
|
+
prefix = options[:prefix]
|
223
|
+
c_i = nil
|
224
|
+
p = nil
|
225
|
+
|
226
|
+
if prefix && name
|
227
|
+
# Get leading zeros
|
228
|
+
p = prefix.scan(/^0+/)[0]
|
229
|
+
|
230
|
+
# Get current index
|
231
|
+
c_i = prefix.gsub(p, '') if p
|
232
|
+
|
233
|
+
# Convert it to Integer to check if we can use it
|
234
|
+
begin
|
235
|
+
c_i = Integer(c_i)
|
236
|
+
name = name.gsub('%i', "#{p}#{c_i + index}")
|
237
|
+
rescue StandardError
|
238
|
+
end
|
239
|
+
elsif name
|
240
|
+
name = name.gsub('%i', i.to_s)
|
241
|
+
end
|
211
242
|
|
212
243
|
extra_template = ''
|
213
244
|
rc = t.info
|
@@ -234,6 +265,10 @@ CommandParser::CmdParser.new(ARGV) do
|
|
234
265
|
end
|
235
266
|
end
|
236
267
|
|
268
|
+
if c_i
|
269
|
+
extra_template.gsub!('%i', "#{p}#{c_i + index}")
|
270
|
+
end
|
271
|
+
|
237
272
|
res = t.instantiate(name, extra_template)
|
238
273
|
|
239
274
|
if !OpenNebula.is_error?(res)
|
@@ -279,7 +314,7 @@ CommandParser::CmdParser.new(ARGV) do
|
|
279
314
|
recursive = (options[:recursive] == true)
|
280
315
|
|
281
316
|
helper.perform_actions(args[0], options, 'Permissions changed') do |t|
|
282
|
-
t.chmod_octet(args[1], recursive)
|
317
|
+
t.chmod_octet(OpenNebulaHelper.to_octet(args[1]), recursive)
|
283
318
|
end
|
284
319
|
end
|
285
320
|
|
data/bin/onevrouter
CHANGED
@@ -251,7 +251,7 @@ CommandParser::CmdParser.new(ARGV) do
|
|
251
251
|
|
252
252
|
command :chmod, chmod_desc, [:range, :vrouterid_list], :octet do
|
253
253
|
helper.perform_actions(args[0], options, 'Permissions changed') do |obj|
|
254
|
-
obj.chmod_octet(args[1])
|
254
|
+
obj.chmod_octet(OpenNebulaHelper.to_octet(args[1]))
|
255
255
|
end
|
256
256
|
end
|
257
257
|
|
@@ -520,59 +520,4 @@ class OneVcenterHelper < OpenNebulaHelper::OneHelper
|
|
520
520
|
opts
|
521
521
|
end
|
522
522
|
|
523
|
-
def clear_tags(vmid)
|
524
|
-
client = Client.new
|
525
|
-
|
526
|
-
vm_pool = VirtualMachinePool.new(client, -1)
|
527
|
-
host_pool = HostPool.new(client)
|
528
|
-
deploy_id = -1
|
529
|
-
host_id = -1
|
530
|
-
hostname = ''
|
531
|
-
|
532
|
-
rc = vm_pool.info
|
533
|
-
raise rc.message if OpenNebula.is_error?(rc)
|
534
|
-
|
535
|
-
rc = host_pool.info
|
536
|
-
raise rc.message if OpenNebula.is_error?(rc)
|
537
|
-
|
538
|
-
vm_pool.each do |vm|
|
539
|
-
next if vm.id.to_s != vmid
|
540
|
-
|
541
|
-
deploy_id = vm.deploy_id
|
542
|
-
vm_history = vm.to_hash['VM']['HISTORY_RECORDS']['HISTORY']
|
543
|
-
hostname = vm_history['HOSTNAME']
|
544
|
-
break
|
545
|
-
end
|
546
|
-
|
547
|
-
host_pool.each do |host|
|
548
|
-
if host.name == hostname
|
549
|
-
host_id = host.id
|
550
|
-
end
|
551
|
-
end
|
552
|
-
|
553
|
-
vi_client = VCenterDriver::VIClient.new_from_host(host_id)
|
554
|
-
vm = VCenterDriver::VirtualMachine
|
555
|
-
.new(vi_client, deploy_id, vmid)
|
556
|
-
|
557
|
-
keys_to_remove = []
|
558
|
-
vm['config.extraConfig'].each do |extraconfig|
|
559
|
-
next unless extraconfig.key.include?('opennebula.disk') ||
|
560
|
-
extraconfig.key.include?('opennebula.vm') ||
|
561
|
-
extraconfig.key.downcase.include?('remotedisplay')
|
562
|
-
|
563
|
-
keys_to_remove << extraconfig.key
|
564
|
-
end
|
565
|
-
|
566
|
-
[vm, keys_to_remove]
|
567
|
-
end
|
568
|
-
|
569
|
-
def remove_keys(vm, keys_to_remove)
|
570
|
-
spec_hash = keys_to_remove.map {|key| { :key => key, :value => '' } }
|
571
|
-
|
572
|
-
spec = RbVmomi::VIM.VirtualMachineConfigSpec(
|
573
|
-
:extraConfig => spec_hash
|
574
|
-
)
|
575
|
-
vm.item.ReconfigVM_Task(:spec => spec).wait_for_completion
|
576
|
-
end
|
577
|
-
|
578
523
|
end
|
@@ -297,7 +297,7 @@ class OneVMHelper < OpenNebulaHelper::OneHelper
|
|
297
297
|
vm.info
|
298
298
|
ids = vm.retrieve_elements("/VM/SNAPSHOTS/SNAPSHOT[NAME='#{id}']/ID")
|
299
299
|
|
300
|
-
return [-1, "#{id} not found or duplicated"] \
|
300
|
+
return [-1, "Snapshot #{id} not found or duplicated"] \
|
301
301
|
if ids.nil? || ids.size > 1
|
302
302
|
|
303
303
|
[0, ids[0].to_i]
|
data/lib/one_helper.rb
CHANGED
@@ -747,12 +747,9 @@ EOT
|
|
747
747
|
ppid = start_pager
|
748
748
|
end
|
749
749
|
|
750
|
-
puts "<#{pname}>"
|
751
|
-
|
752
750
|
puts page
|
753
751
|
|
754
752
|
if elements < size
|
755
|
-
puts "</#{pname}>"
|
756
753
|
return 0
|
757
754
|
end
|
758
755
|
|
@@ -2305,4 +2302,55 @@ EOT
|
|
2305
2302
|
end
|
2306
2303
|
end
|
2307
2304
|
|
2305
|
+
# Convert u=rwx,g=rx,o=r to octet
|
2306
|
+
#
|
2307
|
+
# @param perm [String] Permissions in human readbale format
|
2308
|
+
#
|
2309
|
+
# @return [String] Permissions in octet format
|
2310
|
+
def OpenNebulaHelper.to_octet(perm)
|
2311
|
+
begin
|
2312
|
+
Integer(perm)
|
2313
|
+
perm
|
2314
|
+
rescue StandardError
|
2315
|
+
perm = perm.split(',')
|
2316
|
+
ret = 0
|
2317
|
+
|
2318
|
+
perm.each do |p|
|
2319
|
+
p = p.split('=')
|
2320
|
+
|
2321
|
+
next unless p.size == 2
|
2322
|
+
|
2323
|
+
r = p[1].count('r')
|
2324
|
+
w = p[1].count('w')
|
2325
|
+
x = p[1].count('x')
|
2326
|
+
|
2327
|
+
rwx = (2 ** 0) * x + (2 ** 1) * w + (2 ** 2) * r
|
2328
|
+
|
2329
|
+
case p[0]
|
2330
|
+
when 'u'
|
2331
|
+
ret += rwx * 100
|
2332
|
+
when 'g'
|
2333
|
+
ret += rwx * 10
|
2334
|
+
else
|
2335
|
+
ret += rwx * 1
|
2336
|
+
end
|
2337
|
+
end
|
2338
|
+
|
2339
|
+
if ret == 0
|
2340
|
+
STDERR.puts 'Error in permissions format'
|
2341
|
+
exit(-1)
|
2342
|
+
else
|
2343
|
+
ret = ret.to_s
|
2344
|
+
|
2345
|
+
if ret.size == 1
|
2346
|
+
"00#{ret}"
|
2347
|
+
elsif ret.size == 2
|
2348
|
+
"0#{ret}"
|
2349
|
+
else
|
2350
|
+
ret
|
2351
|
+
end
|
2352
|
+
end
|
2353
|
+
end
|
2354
|
+
end
|
2355
|
+
|
2308
2356
|
end
|
data/share/schemas/xsd/host.xsd
CHANGED
@@ -65,9 +65,11 @@
|
|
65
65
|
<xs:element name="DOMAIN" type="xs:string"/>
|
66
66
|
<xs:element name="FUNCTION" type="xs:string"/>
|
67
67
|
<xs:element name="NUMA_NODE" type="xs:string"/>
|
68
|
+
<xs:element name="PROFILES" type="xs:string" minOccurs="0"/>
|
68
69
|
<xs:element name="SHORT_ADDRESS" type="xs:string"/>
|
69
70
|
<xs:element name="SLOT" type="xs:string"/>
|
70
71
|
<xs:element name="TYPE" type="xs:string"/>
|
72
|
+
<xs:element name="UUID" type="xs:string" minOccurs="0"/>
|
71
73
|
<xs:element name="VENDOR" type="xs:string"/>
|
72
74
|
<xs:element name="VENDOR_NAME" type="xs:string"/>
|
73
75
|
<xs:element name="VMID" type="xs:integer"/>
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: opennebula-cli
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 6.4.
|
4
|
+
version: 6.4.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- OpenNebula
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-
|
11
|
+
date: 2022-10-14 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: opennebula
|
@@ -16,14 +16,14 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - '='
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: 6.4.
|
19
|
+
version: 6.4.2
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - '='
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: 6.4.
|
26
|
+
version: 6.4.2
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: activesupport
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|