opennebula-cli 3.8.0 → 3.9.0.beta
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/bin/oneacct +10 -5
- data/bin/oneacl +5 -1
- data/bin/onecluster +5 -1
- data/bin/onedatastore +5 -1
- data/bin/onegroup +40 -1
- data/bin/onehost +5 -1
- data/bin/oneimage +31 -2
- data/bin/onetemplate +24 -4
- data/bin/oneuser +43 -21
- data/bin/onevm +47 -9
- data/bin/onevnet +15 -1
- data/lib/cli_helper.rb +50 -9
- data/lib/command_parser.rb +79 -37
- data/lib/one_helper/oneacct_helper.rb +4 -4
- data/lib/one_helper/onedatastore_helper.rb +8 -2
- data/lib/one_helper/onegroup_helper.rb +41 -4
- data/lib/one_helper/onehost_helper.rb +9 -0
- data/lib/one_helper/oneimage_helper.rb +15 -10
- data/lib/one_helper/onequota_helper.rb +134 -72
- data/lib/one_helper/oneuser_helper.rb +50 -14
- data/lib/one_helper.rb +210 -16
- metadata +55 -29
data/lib/cli_helper.rb
CHANGED
@@ -31,13 +31,14 @@ module CLIHelper
|
|
31
31
|
# :description => "Order by these columns, column starting with - means decreasing order"
|
32
32
|
#}
|
33
33
|
#
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
34
|
+
FILTER = {
|
35
|
+
:name => "filter",
|
36
|
+
:short => "-f x,y,z",
|
37
|
+
:large => "--filter x,y,z",
|
38
|
+
:format => Array,
|
39
|
+
:description => "Filter data. An array is specified with\n"<<
|
40
|
+
" "*31<<"column=value pairs."
|
41
|
+
}
|
41
42
|
#
|
42
43
|
#HEADER = {
|
43
44
|
# :name => "header",
|
@@ -55,7 +56,7 @@ module CLIHelper
|
|
55
56
|
}
|
56
57
|
|
57
58
|
#OPTIONS = [LIST, ORDER, FILTER, HEADER, DELAY]
|
58
|
-
OPTIONS = [LIST, DELAY]
|
59
|
+
OPTIONS = [LIST, DELAY, FILTER]
|
59
60
|
|
60
61
|
# Sets bold font
|
61
62
|
def CLIHelper.scr_bold
|
@@ -287,7 +288,47 @@ module CLIHelper
|
|
287
288
|
}.compact.join(' ')
|
288
289
|
end
|
289
290
|
|
290
|
-
|
291
|
+
def filter_data!(data, filter)
|
292
|
+
# TBD: add more operators
|
293
|
+
# operators=/(==|=|!=|<|<=|>|>=)/
|
294
|
+
operators=/(=)/
|
295
|
+
|
296
|
+
stems=filter.map do |s|
|
297
|
+
m=s.match(/^(.*?)#{operators}(.*?)$/)
|
298
|
+
if m
|
299
|
+
left, operator, right=m[1..3]
|
300
|
+
index=@default_columns.index(left.to_sym)
|
301
|
+
|
302
|
+
if index
|
303
|
+
{
|
304
|
+
:left => left,
|
305
|
+
:operator => operator,
|
306
|
+
:right => right,
|
307
|
+
:index => index
|
308
|
+
}
|
309
|
+
else
|
310
|
+
STDERR.puts "Column '#{left}' not found"
|
311
|
+
exit(-1)
|
312
|
+
end
|
313
|
+
else
|
314
|
+
STDERR.puts "Expresion '#{s}' incorrect"
|
315
|
+
exit(-1)
|
316
|
+
end
|
317
|
+
end
|
318
|
+
|
319
|
+
data.reject! do |d|
|
320
|
+
pass=true
|
321
|
+
|
322
|
+
stems.each do |s|
|
323
|
+
if d[s[:index]]!=s[:right]
|
324
|
+
pass=false
|
325
|
+
break
|
326
|
+
end
|
327
|
+
end
|
328
|
+
|
329
|
+
!pass
|
330
|
+
end
|
331
|
+
end
|
291
332
|
|
292
333
|
# TBD def sort_data!
|
293
334
|
end
|
data/lib/command_parser.rb
CHANGED
@@ -65,6 +65,9 @@ module CommandParser
|
|
65
65
|
@args = args
|
66
66
|
@options = Hash.new
|
67
67
|
|
68
|
+
@before_proc=nil
|
69
|
+
@comm_name=nil
|
70
|
+
|
68
71
|
define_default_formats
|
69
72
|
|
70
73
|
instance_eval(&block)
|
@@ -97,6 +100,12 @@ module CommandParser
|
|
97
100
|
@name = str
|
98
101
|
end
|
99
102
|
|
103
|
+
# Defines a proc to be called before any command
|
104
|
+
# @param [Proc] block
|
105
|
+
def before_proc(&block)
|
106
|
+
@before_proc = block
|
107
|
+
end
|
108
|
+
|
100
109
|
# Defines a block that will be used to parse the arguments
|
101
110
|
# of the command. Formats defined using this method con be used
|
102
111
|
# in the arguments section of the command method, when defining a new
|
@@ -399,7 +408,7 @@ module CommandParser
|
|
399
408
|
comm = @main
|
400
409
|
elsif
|
401
410
|
if @args[0] && !@args[0].match(/^-/)
|
402
|
-
comm_name = @args.shift.to_sym
|
411
|
+
@comm_name = comm_name = @args.shift.to_sym
|
403
412
|
comm = @commands[comm_name]
|
404
413
|
end
|
405
414
|
end
|
@@ -413,6 +422,8 @@ module CommandParser
|
|
413
422
|
parse(extra_options)
|
414
423
|
|
415
424
|
if comm
|
425
|
+
@before_proc.call if @before_proc
|
426
|
+
|
416
427
|
check_args!(comm_name, comm[:arity], comm[:args_format])
|
417
428
|
|
418
429
|
rc = comm[:proc].call
|
@@ -428,9 +439,12 @@ module CommandParser
|
|
428
439
|
private
|
429
440
|
|
430
441
|
def parse(extra_options)
|
442
|
+
with_proc=Array.new
|
443
|
+
|
431
444
|
@cmdparse=OptionParser.new do |opts|
|
432
445
|
merge = @available_options
|
433
446
|
merge = @available_options + extra_options if extra_options
|
447
|
+
|
434
448
|
merge.flatten.each do |e|
|
435
449
|
args = []
|
436
450
|
args << e[:short] if e[:short]
|
@@ -440,16 +454,8 @@ module CommandParser
|
|
440
454
|
|
441
455
|
opts.on(*args) do |o|
|
442
456
|
if e[:proc]
|
443
|
-
|
444
|
-
|
445
|
-
if rc[0] == 0
|
446
|
-
options[e[:name].to_sym] = rc[1]
|
447
|
-
else
|
448
|
-
puts rc[1]
|
449
|
-
puts "option #{e[:name]}: Parsing error"
|
450
|
-
exit -1
|
451
|
-
end
|
452
|
-
end
|
457
|
+
@options[e[:name].to_sym]=o
|
458
|
+
with_proc<<e
|
453
459
|
elsif e[:name]=="help"
|
454
460
|
print_help
|
455
461
|
exit
|
@@ -469,6 +475,19 @@ module CommandParser
|
|
469
475
|
puts e.message
|
470
476
|
exit -1
|
471
477
|
end
|
478
|
+
|
479
|
+
with_proc.each do |e|
|
480
|
+
rc = e[:proc].call(@options[e[:name].to_sym], @options)
|
481
|
+
if rc.instance_of?(Array)
|
482
|
+
if rc[0] == 0
|
483
|
+
@options[e[:name].to_sym] = rc[1]
|
484
|
+
else
|
485
|
+
puts rc[1]
|
486
|
+
puts "option #{e[:name]}: Parsing error"
|
487
|
+
exit -1
|
488
|
+
end
|
489
|
+
end
|
490
|
+
end
|
472
491
|
end
|
473
492
|
|
474
493
|
def check_args!(name, arity, args_format)
|
@@ -479,15 +498,9 @@ module CommandParser
|
|
479
498
|
else
|
480
499
|
puts "one parameter to run"
|
481
500
|
end
|
482
|
-
puts
|
483
|
-
puts "Usage:"
|
484
501
|
|
485
|
-
|
486
|
-
|
487
|
-
else
|
488
|
-
print " #{name} "
|
489
|
-
print_command(@commands[name])
|
490
|
-
end
|
502
|
+
print_command_help(name)
|
503
|
+
|
491
504
|
exit -1
|
492
505
|
else
|
493
506
|
id=0
|
@@ -550,6 +563,14 @@ module CommandParser
|
|
550
563
|
########################################################################
|
551
564
|
|
552
565
|
def print_help
|
566
|
+
if @comm_name
|
567
|
+
print_command_help(@comm_name)
|
568
|
+
else
|
569
|
+
print_all_commands_help
|
570
|
+
end
|
571
|
+
end
|
572
|
+
|
573
|
+
def print_all_commands_help
|
553
574
|
if @usage
|
554
575
|
puts "## SYNOPSIS"
|
555
576
|
puts
|
@@ -570,37 +591,58 @@ module CommandParser
|
|
570
591
|
end
|
571
592
|
end
|
572
593
|
|
594
|
+
def print_command_help(name)
|
595
|
+
command=@commands[name]
|
596
|
+
|
597
|
+
if !command
|
598
|
+
STDERR.puts "Command '#{name}' not found"
|
599
|
+
return print_all_commands_help
|
600
|
+
end
|
601
|
+
|
602
|
+
puts "## USAGE"
|
603
|
+
print "#{name} "
|
604
|
+
print_command(@commands[name])
|
605
|
+
|
606
|
+
puts "## OPTIONS"
|
607
|
+
command[:options].flatten.each do |o|
|
608
|
+
print_option(o)
|
609
|
+
end
|
610
|
+
|
611
|
+
@available_options.each do |o|
|
612
|
+
print_option o
|
613
|
+
end
|
614
|
+
end
|
573
615
|
|
574
616
|
def print_options
|
575
617
|
puts "## OPTIONS"
|
576
618
|
|
577
619
|
shown_opts = Array.new
|
578
|
-
|
579
|
-
|
580
|
-
value[:options].flatten.each { |o|
|
620
|
+
@commands.each do |key,value|
|
621
|
+
value[:options].flatten.each do |o|
|
581
622
|
if shown_opts.include?(o[:name])
|
582
623
|
next
|
583
624
|
else
|
584
625
|
shown_opts << o[:name]
|
585
626
|
|
586
|
-
|
587
|
-
str << o[:short].split(' ').first << ', ' if o[:short]
|
588
|
-
str << o[:large]
|
589
|
-
|
590
|
-
printf opt_format, str, o[:description]
|
591
|
-
puts
|
627
|
+
print_option(o)
|
592
628
|
end
|
593
|
-
|
594
|
-
|
629
|
+
end
|
630
|
+
end
|
595
631
|
|
596
|
-
@available_options.each
|
597
|
-
|
598
|
-
|
599
|
-
|
632
|
+
@available_options.each do |o|
|
633
|
+
print_option o
|
634
|
+
end
|
635
|
+
end
|
600
636
|
|
601
|
-
|
602
|
-
|
603
|
-
|
637
|
+
def print_option(o)
|
638
|
+
opt_format = "#{' '*5}%-25s %s"
|
639
|
+
|
640
|
+
str = ""
|
641
|
+
str << o[:short].split(' ').first << ', ' if o[:short]
|
642
|
+
str << o[:large]
|
643
|
+
|
644
|
+
printf opt_format, str, o[:description]
|
645
|
+
puts
|
604
646
|
end
|
605
647
|
|
606
648
|
def print_commands
|
@@ -33,10 +33,10 @@ class AcctHelper < OpenNebulaHelper::OneHelper
|
|
33
33
|
:format => String # TODO Time
|
34
34
|
}
|
35
35
|
|
36
|
-
|
37
|
-
:name => "
|
36
|
+
USERFILTER = {
|
37
|
+
:name => "userfilter",
|
38
38
|
:short => "-u user",
|
39
|
-
:large => "--
|
39
|
+
:large => "--userfilter user" ,
|
40
40
|
:description => "User name or id to filter the results",
|
41
41
|
:format => String,
|
42
42
|
:proc => lambda { |o, options|
|
@@ -95,7 +95,7 @@ class AcctHelper < OpenNebulaHelper::OneHelper
|
|
95
95
|
:description => "Split the output in a table for each VM"
|
96
96
|
}
|
97
97
|
|
98
|
-
ACCT_OPTIONS = [START_TIME, END_TIME,
|
98
|
+
ACCT_OPTIONS = [START_TIME, END_TIME, USERFILTER, GROUP, HOST, XPATH, XML, JSON, SPLIT]
|
99
99
|
|
100
100
|
|
101
101
|
ACCT_TABLE = CLIHelper::ShowTable.new("oneacct.yaml", nil) do
|
@@ -60,7 +60,12 @@ class OneDatastoreHelper < OpenNebulaHelper::OneHelper
|
|
60
60
|
end
|
61
61
|
end
|
62
62
|
|
63
|
-
column :TYPE, "Datastore
|
63
|
+
column :TYPE, "Datastore type", :left, :size=>4 do |d|
|
64
|
+
type = Datastore::DATASTORE_TYPES[d["TYPE"].to_i]
|
65
|
+
Datastore::SHORT_DATASTORE_TYPES[type]
|
66
|
+
end
|
67
|
+
|
68
|
+
column :DS, "Datastore driver", :left, :size=>8 do |d|
|
64
69
|
d["DS_MAD"]
|
65
70
|
end
|
66
71
|
|
@@ -68,7 +73,7 @@ class OneDatastoreHelper < OpenNebulaHelper::OneHelper
|
|
68
73
|
d["TM_MAD"]
|
69
74
|
end
|
70
75
|
|
71
|
-
default :ID, :NAME, :CLUSTER, :IMAGES, :TYPE, :TM
|
76
|
+
default :ID, :NAME, :CLUSTER, :IMAGES, :TYPE, :DS, :TM
|
72
77
|
end
|
73
78
|
|
74
79
|
table
|
@@ -101,6 +106,7 @@ class OneDatastoreHelper < OpenNebulaHelper::OneHelper
|
|
101
106
|
puts str % ["GROUP", datastore['GNAME']]
|
102
107
|
puts str % ["CLUSTER", OpenNebulaHelper.cluster_str(datastore['CLUSTER'])]
|
103
108
|
|
109
|
+
puts str % ["TYPE", datastore.type_str]
|
104
110
|
puts str % ["DS_MAD", datastore['DS_MAD']]
|
105
111
|
puts str % ["TM_MAD", datastore['TM_MAD']]
|
106
112
|
puts str % ["BASE PATH",datastore['BASE_PATH']]
|
@@ -48,6 +48,13 @@ class OneGroupHelper < OpenNebulaHelper::OneHelper
|
|
48
48
|
def format_pool(options)
|
49
49
|
config_file = self.class.table_conf
|
50
50
|
|
51
|
+
system = System.new(@client)
|
52
|
+
default_quotas = system.get_group_quotas()
|
53
|
+
|
54
|
+
if OpenNebula::is_error?(default_quotas)
|
55
|
+
raise "Error retrieving the default group quotas: #{default_quotas.message}"
|
56
|
+
end
|
57
|
+
|
51
58
|
table = CLIHelper::ShowTable.new(config_file, self) do
|
52
59
|
column :ID, "ONE identifier for the Group", :size=>4 do |d|
|
53
60
|
d["ID"]
|
@@ -67,7 +74,14 @@ class OneGroupHelper < OpenNebulaHelper::OneHelper
|
|
67
74
|
|
68
75
|
column :VMS , "Number of VMS", :size=>9 do |d|
|
69
76
|
if d.has_key?('VM_QUOTA') and d['VM_QUOTA'].has_key?('VM')
|
70
|
-
|
77
|
+
limit = d['VM_QUOTA']['VM']["VMS"]
|
78
|
+
|
79
|
+
if limit == "-1"
|
80
|
+
limit = default_quotas['VM_QUOTA/VM/VMS']
|
81
|
+
limit = "0" if limit.nil? || limit == ""
|
82
|
+
end
|
83
|
+
|
84
|
+
"%3d / %3d" % [d['VM_QUOTA']['VM']["VMS_USED"], limit]
|
71
85
|
else
|
72
86
|
"-"
|
73
87
|
end
|
@@ -75,8 +89,16 @@ class OneGroupHelper < OpenNebulaHelper::OneHelper
|
|
75
89
|
|
76
90
|
column :MEMORY, "Total memory allocated to user VMs", :size=>17 do |d|
|
77
91
|
if d.has_key?('VM_QUOTA') and d['VM_QUOTA'].has_key?('VM')
|
92
|
+
limit = d['VM_QUOTA']['VM']["MEMORY"]
|
93
|
+
|
94
|
+
if limit == "-1"
|
95
|
+
limit = default_quotas['VM_QUOTA/VM/MEMORY']
|
96
|
+
limit = "0" if limit.nil? || limit == ""
|
97
|
+
end
|
98
|
+
|
99
|
+
d['VM_QUOTA']['VM']['MEMORY_USED']
|
78
100
|
"%7s / %7s" % [OpenNebulaHelper.unit_to_str(d['VM_QUOTA']['VM']["MEMORY_USED"].to_i,{},"M"),
|
79
|
-
OpenNebulaHelper.unit_to_str(
|
101
|
+
OpenNebulaHelper.unit_to_str(limit.to_i,{},"M")]
|
80
102
|
else
|
81
103
|
"-"
|
82
104
|
end
|
@@ -84,7 +106,14 @@ class OneGroupHelper < OpenNebulaHelper::OneHelper
|
|
84
106
|
|
85
107
|
column :CPU, "Total CPU allocated to user VMs", :size=>11 do |d|
|
86
108
|
if d.has_key?('VM_QUOTA') and d['VM_QUOTA'].has_key?('VM')
|
87
|
-
|
109
|
+
limit = d['VM_QUOTA']['VM']["CPU"]
|
110
|
+
|
111
|
+
if limit == "-1"
|
112
|
+
limit = default_quotas['VM_QUOTA/VM/CPU']
|
113
|
+
limit = "0" if limit.nil? || limit == ""
|
114
|
+
end
|
115
|
+
|
116
|
+
"%4.0f / %4.0f" % [d['VM_QUOTA']['VM']["CPU_USED"], limit]
|
88
117
|
else
|
89
118
|
"-"
|
90
119
|
end
|
@@ -113,6 +142,13 @@ class OneGroupHelper < OpenNebulaHelper::OneHelper
|
|
113
142
|
end
|
114
143
|
|
115
144
|
def format_resource(group)
|
145
|
+
system = System.new(@client)
|
146
|
+
default_quotas = system.get_group_quotas()
|
147
|
+
|
148
|
+
if OpenNebula::is_error?(default_quotas)
|
149
|
+
raise "Error retrieving the default group quotas: #{default_quotas.message}"
|
150
|
+
end
|
151
|
+
|
116
152
|
str="%-15s: %-20s"
|
117
153
|
str_h1="%-80s"
|
118
154
|
|
@@ -129,6 +165,7 @@ class OneGroupHelper < OpenNebulaHelper::OneHelper
|
|
129
165
|
|
130
166
|
group_hash = group.to_hash
|
131
167
|
|
132
|
-
OneQuotaHelper.
|
168
|
+
helper = OneQuotaHelper.new
|
169
|
+
helper.format_quota(group_hash['GROUP'], default_quotas)
|
133
170
|
end
|
134
171
|
end
|
@@ -15,6 +15,7 @@
|
|
15
15
|
#--------------------------------------------------------------------------- #
|
16
16
|
|
17
17
|
require 'one_helper'
|
18
|
+
require 'one_helper/onevm_helper'
|
18
19
|
|
19
20
|
class OneHostHelper < OpenNebulaHelper::OneHelper
|
20
21
|
def self.rname
|
@@ -192,5 +193,13 @@ class OneHostHelper < OpenNebulaHelper::OneHelper
|
|
192
193
|
CLIHelper.print_header(str_h1 % "MONITORING INFORMATION", false)
|
193
194
|
|
194
195
|
puts host.template_str
|
196
|
+
|
197
|
+
puts
|
198
|
+
CLIHelper.print_header("VIRTUAL MACHINES", false)
|
199
|
+
puts
|
200
|
+
|
201
|
+
onevm_helper=OneVMHelper.new
|
202
|
+
onevm_helper.client=@client
|
203
|
+
onevm_helper.list_pool({:filter=>["HOST=#{host.name}"]}, false)
|
195
204
|
end
|
196
205
|
end
|
@@ -34,14 +34,14 @@ class OneImageHelper < OpenNebulaHelper::OneHelper
|
|
34
34
|
:name => "type",
|
35
35
|
:large => "--type type",
|
36
36
|
:format => String,
|
37
|
-
:description => "Type of the new Image:
|
37
|
+
:description => "Type of the new Image: #{Image::IMAGE_TYPES.join(", ")}",
|
38
38
|
:proc => lambda do |o, options|
|
39
39
|
type=o.strip.upcase
|
40
40
|
|
41
|
-
if
|
41
|
+
if Image::IMAGE_TYPES.include? type
|
42
42
|
[0, type]
|
43
43
|
else
|
44
|
-
[-1, "Type should be
|
44
|
+
[-1, "Type should be: #{Image::IMAGE_TYPES.join(", ")}"]
|
45
45
|
end
|
46
46
|
end
|
47
47
|
},
|
@@ -53,7 +53,8 @@ class OneImageHelper < OpenNebulaHelper::OneHelper
|
|
53
53
|
{
|
54
54
|
:name => "prefix",
|
55
55
|
:large => "--prefix prefix",
|
56
|
-
:description => "Device prefix for the disk (eg. hd, sd, xvd
|
56
|
+
:description => "Device prefix for the disk (eg. hd, sd, xvd\n"<<
|
57
|
+
" "*31<<"or vd)",
|
57
58
|
:format => String,
|
58
59
|
:proc => lambda do |o, options|
|
59
60
|
prefix=o.strip.downcase
|
@@ -76,7 +77,9 @@ class OneImageHelper < OpenNebulaHelper::OneHelper
|
|
76
77
|
:description => "Path of the image file",
|
77
78
|
:format => String,
|
78
79
|
:proc => lambda do |o, options|
|
79
|
-
if o
|
80
|
+
if o.match(/^https?:\/\//)
|
81
|
+
next [0, o]
|
82
|
+
elsif o[0,1]=='/'
|
80
83
|
path=o
|
81
84
|
else
|
82
85
|
path=Dir.pwd+"/"+o
|
@@ -113,7 +116,8 @@ class OneImageHelper < OpenNebulaHelper::OneHelper
|
|
113
116
|
:name => "source",
|
114
117
|
:large => "--source source",
|
115
118
|
:description =>
|
116
|
-
"Source to be used. Useful for not file-based
|
119
|
+
"Source to be used. Useful for not file-based\n"<<
|
120
|
+
" "*31<<"images",
|
117
121
|
:format => String
|
118
122
|
},
|
119
123
|
{
|
@@ -147,8 +151,8 @@ class OneImageHelper < OpenNebulaHelper::OneHelper
|
|
147
151
|
{
|
148
152
|
:name => "fstype",
|
149
153
|
:large => "--fstype fstype",
|
150
|
-
:description => "Type of file system to be built. This can be "<<
|
151
|
-
|
154
|
+
:description => "Type of file system to be built. This can be \n"<<
|
155
|
+
" "*31<<"any value understood by mkfs unix command.",
|
152
156
|
:format => String,
|
153
157
|
:proc => lambda do |o, options|
|
154
158
|
if !options[:type] || !(options[:type].upcase=='DATABLOCK')
|
@@ -157,7 +161,8 @@ class OneImageHelper < OpenNebulaHelper::OneHelper
|
|
157
161
|
[0, o]
|
158
162
|
end
|
159
163
|
end
|
160
|
-
}
|
164
|
+
},
|
165
|
+
OpenNebulaHelper::DRY
|
161
166
|
]
|
162
167
|
|
163
168
|
def self.rname
|
@@ -318,7 +323,7 @@ class OneImageHelper < OpenNebulaHelper::OneHelper
|
|
318
323
|
end
|
319
324
|
|
320
325
|
template=create_image_variables(
|
321
|
-
options, template_options-[:persistent])
|
326
|
+
options, template_options-[:persistent, :dry])
|
322
327
|
|
323
328
|
template<<"PERSISTENT=YES\n" if options[:persistent]
|
324
329
|
|