opennebula-cli 3.8.0.beta1

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.
@@ -0,0 +1,266 @@
1
+ # -------------------------------------------------------------------------- #
2
+ # Copyright 2002-2012, OpenNebula Project Leads (OpenNebula.org) #
3
+ # #
4
+ # Licensed under the Apache License, Version 2.0 (the "License"); you may #
5
+ # not use this file except in compliance with the License. You may obtain #
6
+ # a copy of the License at #
7
+ # #
8
+ # http://www.apache.org/licenses/LICENSE-2.0 #
9
+ # #
10
+ # Unless required by applicable law or agreed to in writing, software #
11
+ # distributed under the License is distributed on an "AS IS" BASIS, #
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. #
13
+ # See the License for the specific language governing permissions and #
14
+ # limitations under the License. #
15
+ #--------------------------------------------------------------------------- #
16
+
17
+ require 'one_helper'
18
+
19
+ class OneVMHelper < OpenNebulaHelper::OneHelper
20
+ MULTIPLE={
21
+ :name => "multiple",
22
+ :short => "-m x",
23
+ :large => "--multiple x",
24
+ :format => Integer,
25
+ :description => "Instance multiple VMs"
26
+ }
27
+
28
+ IMAGE = {
29
+ :name => "image",
30
+ :short => "-i id|name",
31
+ :large => "--image id|name" ,
32
+ :description => "Selects the image",
33
+ :format => String,
34
+ :proc => lambda { |o, options|
35
+ OpenNebulaHelper.rname_to_id(o, "IMAGE")
36
+ }
37
+ }
38
+
39
+ FILE = {
40
+ :name => "file",
41
+ :short => "-f file",
42
+ :large => "--file file" ,
43
+ :description => "Selects the template file",
44
+ :format => String,
45
+ :proc => lambda { |o, options|
46
+ if File.file?(o)
47
+ options[:file] = o
48
+ else
49
+ exit -1
50
+ end
51
+ }
52
+ }
53
+
54
+ def self.rname
55
+ "VM"
56
+ end
57
+
58
+ def self.conf_file
59
+ "onevm.yaml"
60
+ end
61
+
62
+ def self.state_to_str(id, lcm_id)
63
+ id = id.to_i
64
+ state_str = VirtualMachine::VM_STATE[id]
65
+ short_state_str = VirtualMachine::SHORT_VM_STATES[state_str]
66
+
67
+ if short_state_str=="actv"
68
+ lcm_id = lcm_id.to_i
69
+ lcm_state_str = VirtualMachine::LCM_STATE[lcm_id]
70
+ return VirtualMachine::SHORT_LCM_STATES[lcm_state_str]
71
+ end
72
+
73
+ return short_state_str
74
+ end
75
+
76
+ def format_pool(options)
77
+ config_file = self.class.table_conf
78
+
79
+ table = CLIHelper::ShowTable.new(config_file, self) do
80
+ column :ID, "ONE identifier for Virtual Machine", :size=>6 do |d|
81
+ d["ID"]
82
+ end
83
+
84
+ column :NAME, "Name of the Virtual Machine", :left,
85
+ :size=>15 do |d|
86
+ if d["RESCHED"] == "1"
87
+ "*#{d["NAME"]}"
88
+ else
89
+ d["NAME"]
90
+ end
91
+ end
92
+
93
+ column :USER, "Username of the Virtual Machine owner", :left,
94
+ :size=>8 do |d|
95
+ helper.user_name(d, options)
96
+ end
97
+
98
+ column :GROUP, "Group of the Virtual Machine", :left,
99
+ :size=>8 do |d|
100
+ helper.group_name(d, options)
101
+ end
102
+
103
+ column :STAT, "Actual status", :size=>4 do |d,e|
104
+ OneVMHelper.state_to_str(d["STATE"], d["LCM_STATE"])
105
+ end
106
+
107
+ column :UCPU, "CPU percentage used by the VM", :size=>4 do |d|
108
+ d["CPU"]
109
+ end
110
+
111
+ column :UMEM, "Memory used by the VM", :size=>7 do |d|
112
+ OpenNebulaHelper.unit_to_str(d["MEMORY"].to_i, options)
113
+ end
114
+
115
+ column :HOST, "Host where the VM is running", :left, :size=>10 do |d|
116
+ if d['HISTORY_RECORDS'] && d['HISTORY_RECORDS']['HISTORY']
117
+ state_str = VirtualMachine::VM_STATE[d['STATE'].to_i]
118
+ if %w{ACTIVE SUSPENDED}.include? state_str
119
+ d['HISTORY_RECORDS']['HISTORY']['HOSTNAME']
120
+ end
121
+ end
122
+ end
123
+
124
+ column :TIME, "Time since the VM was submitted", :size=>10 do |d|
125
+ stime = d["STIME"].to_i
126
+ etime = d["ETIME"]=="0" ? Time.now.to_i : d["ETIME"].to_i
127
+ dtime = etime-stime
128
+ OpenNebulaHelper.period_to_str(dtime, false)
129
+ end
130
+
131
+ default :ID, :USER, :GROUP, :NAME, :STAT, :UCPU, :UMEM, :HOST,
132
+ :TIME
133
+ end
134
+
135
+ table
136
+ end
137
+
138
+ private
139
+
140
+ def factory(id=nil)
141
+ if id
142
+ OpenNebula::VirtualMachine.new_with_id(id, @client)
143
+ else
144
+ xml=OpenNebula::VirtualMachine.build_xml
145
+ OpenNebula::VirtualMachine.new(xml, @client)
146
+ end
147
+ end
148
+
149
+ def factory_pool(user_flag=-2)
150
+ OpenNebula::VirtualMachinePool.new(@client, user_flag)
151
+ end
152
+
153
+ def format_resource(vm)
154
+ str_h1="%-80s"
155
+ str="%-20s: %-20s"
156
+
157
+ CLIHelper.print_header(
158
+ str_h1 % "VIRTUAL MACHINE #{vm['ID']} INFORMATION")
159
+ puts str % ["ID", vm.id.to_s]
160
+ puts str % ["NAME", vm.name]
161
+ puts str % ["USER", vm['UNAME']]
162
+ puts str % ["GROUP", vm['GNAME']]
163
+ puts str % ["STATE", vm.state_str]
164
+ puts str % ["LCM_STATE", vm.lcm_state_str]
165
+ puts str % ["RESCHED", OpenNebulaHelper.boolean_to_str(vm['RESCHED'])]
166
+ puts str % ["HOST",
167
+ vm['/VM/HISTORY_RECORDS/HISTORY[last()]/HOSTNAME']] if
168
+ %w{ACTIVE SUSPENDED}.include? vm.state_str
169
+ puts str % ["START TIME",
170
+ OpenNebulaHelper.time_to_str(vm['/VM/STIME'])]
171
+ puts str % ["END TIME",
172
+ OpenNebulaHelper.time_to_str(vm['/VM/ETIME'])]
173
+ value=vm['DEPLOY_ID']
174
+ puts str % ["DEPLOY ID", value=="" ? "-" : value]
175
+
176
+ puts
177
+
178
+ CLIHelper.print_header(str_h1 % "VIRTUAL MACHINE MONITORING",false)
179
+ poll_attrs = {
180
+ "USED MEMORY" => "MEMORY",
181
+ "USED CPU" => "CPU",
182
+ "NET_TX" => "NET_TX",
183
+ "NET_RX" => "NET_RX"
184
+ }
185
+
186
+ poll_attrs.each { |k,v|
187
+ if k == "USED CPU"
188
+ puts str % [k,vm[v]]
189
+ elsif k == "USED MEMORY"
190
+ puts str % [k, OpenNebulaHelper.unit_to_str(vm[v].to_i, {})]
191
+ else
192
+ puts str % [k, OpenNebulaHelper.unit_to_str(vm[v].to_i/1024, {})]
193
+ end
194
+ }
195
+ puts
196
+
197
+ CLIHelper.print_header(str_h1 % "PERMISSIONS",false)
198
+
199
+ ["OWNER", "GROUP", "OTHER"].each { |e|
200
+ mask = "---"
201
+ mask[0] = "u" if vm["PERMISSIONS/#{e}_U"] == "1"
202
+ mask[1] = "m" if vm["PERMISSIONS/#{e}_M"] == "1"
203
+ mask[2] = "a" if vm["PERMISSIONS/#{e}_A"] == "1"
204
+
205
+ puts str % [e, mask]
206
+ }
207
+ puts
208
+
209
+ CLIHelper.print_header(str_h1 % "VIRTUAL MACHINE TEMPLATE",false)
210
+ puts vm.template_str
211
+
212
+ if vm.has_elements?("/VM/HISTORY_RECORDS")
213
+ puts
214
+
215
+
216
+ CLIHelper.print_header(str_h1 % "VIRTUAL MACHINE HISTORY",false)
217
+ format_history(vm)
218
+ end
219
+ end
220
+
221
+ def format_history(vm)
222
+ table=CLIHelper::ShowTable.new(nil, self) do
223
+ column :SEQ, "Sequence number", :size=>4 do |d|
224
+ d["SEQ"]
225
+ end
226
+
227
+ column :HOST, "Host name of the VM container", :left, :size=>15 do |d|
228
+ d["HOSTNAME"]
229
+ end
230
+
231
+ column :REASON, "VM state change reason", :left, :size=>6 do |d|
232
+ VirtualMachine.get_reason d["REASON"]
233
+ end
234
+
235
+ column :START, "Time when the state changed", :size=>15 do |d|
236
+ OpenNebulaHelper.time_to_str(d['STIME'])
237
+ end
238
+
239
+ column :TIME, "Total time in this state", :size=>15 do |d|
240
+ stime = d["STIME"].to_i
241
+ etime = d["ETIME"]=="0" ? Time.now.to_i : d["ETIME"].to_i
242
+ dtime = etime-stime
243
+ OpenNebulaHelper.period_to_str(dtime)
244
+ end
245
+
246
+ column :PROLOG_TIME, "Prolog time for this state", :size=>15 do |d|
247
+ stime = d["PSTIME"].to_i
248
+ if d["PSTIME"]=="0"
249
+ etime=0
250
+ else
251
+ etime = d["PETIME"]=="0" ? Time.now.to_i: d["PETIME"].to_i
252
+ end
253
+ dtime = etime-stime
254
+ OpenNebulaHelper.period_to_str(dtime)
255
+ end
256
+
257
+ default :SEQ, :HOST, :REASON, :START, :TIME, :PROLOG_TIME
258
+ end
259
+
260
+ vm_hash=vm.to_hash
261
+
262
+ history=[vm_hash['VM']['HISTORY_RECORDS']['HISTORY']].flatten
263
+
264
+ table.show(history)
265
+ end
266
+ end
@@ -0,0 +1,156 @@
1
+ # -------------------------------------------------------------------------- #
2
+ # Copyright 2002-2012, OpenNebula Project Leads (OpenNebula.org) #
3
+ # #
4
+ # Licensed under the Apache License, Version 2.0 (the "License"); you may #
5
+ # not use this file except in compliance with the License. You may obtain #
6
+ # a copy of the License at #
7
+ # #
8
+ # http://www.apache.org/licenses/LICENSE-2.0 #
9
+ # #
10
+ # Unless required by applicable law or agreed to in writing, software #
11
+ # distributed under the License is distributed on an "AS IS" BASIS, #
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. #
13
+ # See the License for the specific language governing permissions and #
14
+ # limitations under the License. #
15
+ #--------------------------------------------------------------------------- #
16
+
17
+ require 'one_helper'
18
+
19
+ class OneVNetHelper < OpenNebulaHelper::OneHelper
20
+ def self.rname
21
+ "VNET"
22
+ end
23
+
24
+ def self.conf_file
25
+ "onevnet.yaml"
26
+ end
27
+
28
+ def self.type_to_str(id)
29
+ id = id.to_i
30
+ type_str = VirtualNetwork::VN_TYPES[id]
31
+ return VirtualNetwork::SHORT_VN_TYPES[type_str]
32
+ end
33
+
34
+ def format_pool(options)
35
+ config_file = self.class.table_conf
36
+
37
+ table = CLIHelper::ShowTable.new(config_file, self) do
38
+ column :ID, "ONE identifier for Virtual Network", :size=>4 do |d|
39
+ d["ID"]
40
+ end
41
+
42
+ column :USER, "Username of the Virtual Network owner", :left,
43
+ :size=>12 do |d|
44
+ helper.user_name(d, options)
45
+ end
46
+
47
+ column :GROUP, "Group of the Virtual Network", :left,
48
+ :size=>12 do |d|
49
+ helper.group_name(d, options)
50
+ end
51
+
52
+ column :NAME, "Name of the Virtual Network", :left,
53
+ :size=>15 do |d|
54
+ d["NAME"]
55
+ end
56
+
57
+ column :CLUSTER, "Name of the Cluster", :left, :size=>10 do |d|
58
+ OpenNebulaHelper.cluster_str(d["CLUSTER"])
59
+ end
60
+
61
+ column :TYPE, "Type of Virtual Network", :size=>6 do |d|
62
+ OneVNetHelper.type_to_str(d["TYPE"])
63
+ end
64
+
65
+ column :SIZE, "Size of the Virtual Network", :size=>5 do |d|
66
+ d["SIZE"]
67
+ end
68
+
69
+ column :BRIDGE, "Bridge associated to the Virtual Network", :left,
70
+ :size=>8 do |d|
71
+ d["BRIDGE"]
72
+ end
73
+
74
+ column :LEASES, "Number of this Virtual Network's given leases",
75
+ :size=>6 do |d|
76
+ d["TOTAL_LEASES"]
77
+ end
78
+
79
+ default :ID, :USER, :GROUP, :NAME, :CLUSTER, :TYPE, :BRIDGE, :LEASES
80
+ end
81
+
82
+ table
83
+ end
84
+
85
+ private
86
+
87
+ def factory(id=nil)
88
+ if id
89
+ OpenNebula::VirtualNetwork.new_with_id(id, @client)
90
+ else
91
+ xml=OpenNebula::VirtualNetwork.build_xml
92
+ OpenNebula::VirtualNetwork.new(xml, @client)
93
+ end
94
+ end
95
+
96
+ def factory_pool(user_flag=-2)
97
+ OpenNebula::VirtualNetworkPool.new(@client, user_flag)
98
+ end
99
+
100
+ def format_resource(vn)
101
+ str_h1="%-80s"
102
+ CLIHelper.print_header(str_h1 %
103
+ ["VIRTUAL NETWORK #{vn.id.to_s} INFORMATION"])
104
+
105
+ str="%-15s: %-20s"
106
+ puts str % ["ID", vn.id.to_s]
107
+ puts str % ["NAME", vn['NAME']]
108
+ puts str % ["USER", vn['UNAME']]
109
+ puts str % ["GROUP", vn['GNAME']]
110
+ puts str % ["CLUSTER", OpenNebulaHelper.cluster_str(vn['CLUSTER'])]
111
+ puts str % ["TYPE", vn.type_str]
112
+ puts str % ["BRIDGE", vn["BRIDGE"]]
113
+ puts str % ["VLAN", OpenNebulaHelper.boolean_to_str(vn['VLAN'])]
114
+ puts str % ["PHYSICAL DEVICE", vn["PHYDEV"]] if vn["PHYDEV"]
115
+ puts str % ["VLAN ID", vn["VLAN_ID"]] if vn["VLAN_ID"]
116
+ puts str % ["USED LEASES", vn['TOTAL_LEASES']]
117
+ puts
118
+
119
+ CLIHelper.print_header(str_h1 % "PERMISSIONS",false)
120
+
121
+ ["OWNER", "GROUP", "OTHER"].each { |e|
122
+ mask = "---"
123
+ mask[0] = "u" if vn["PERMISSIONS/#{e}_U"] == "1"
124
+ mask[1] = "m" if vn["PERMISSIONS/#{e}_M"] == "1"
125
+ mask[2] = "a" if vn["PERMISSIONS/#{e}_A"] == "1"
126
+
127
+ puts str % [e, mask]
128
+ }
129
+ puts
130
+
131
+ CLIHelper.print_header(str_h1 % ["VIRTUAL NETWORK TEMPLATE"], false)
132
+
133
+ puts vn.template_str(false)
134
+
135
+ if vn.type_str == "RANGED"
136
+ puts
137
+ CLIHelper.print_header(str_h1 % ["RANGE"], false)
138
+ puts str % ["IP_START", vn['RANGE/IP_START']]
139
+ puts str % ["IP_END", vn['RANGE/IP_END']]
140
+ end
141
+
142
+ lease_types = [ ["LEASES ON HOLD", 'LEASE[USED=1 and VID=-1]'],
143
+ ["USED LEASES", 'LEASE[USED=1 and VID>-1]'],
144
+ ["FREE LEASES", 'LEASE[USED=0]'] ]
145
+
146
+ lease_types.each { |pair|
147
+ leases_str = vn.template_like_str('/VNET/LEASES', false, pair[1])
148
+
149
+ if !leases_str.empty?
150
+ puts
151
+ CLIHelper.print_header(str_h1 % [pair[0]], false)
152
+ puts leases_str
153
+ end
154
+ }
155
+ end
156
+ end
data/lib/one_helper.rb ADDED
@@ -0,0 +1,609 @@
1
+ # -------------------------------------------------------------------------- #
2
+ # Copyright 2002-2012, OpenNebula Project Leads (OpenNebula.org) #
3
+ # #
4
+ # Licensed under the Apache License, Version 2.0 (the "License"); you may #
5
+ # not use this file except in compliance with the License. You may obtain #
6
+ # a copy of the License at #
7
+ # #
8
+ # http://www.apache.org/licenses/LICENSE-2.0 #
9
+ # #
10
+ # Unless required by applicable law or agreed to in writing, software #
11
+ # distributed under the License is distributed on an "AS IS" BASIS, #
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. #
13
+ # See the License for the specific language governing permissions and #
14
+ # limitations under the License. #
15
+ #--------------------------------------------------------------------------- #
16
+
17
+ require 'cli_helper'
18
+
19
+ require 'OpenNebula'
20
+ include OpenNebula
21
+
22
+ module OpenNebulaHelper
23
+ ONE_VERSION=<<-EOT
24
+ OpenNebula #{OpenNebula::VERSION}
25
+ Copyright 2002-2012, OpenNebula Project Leads (OpenNebula.org)
26
+
27
+ Licensed under the Apache License, Version 2.0 (the "License"); you may
28
+ not use this file except in compliance with the License. You may obtain
29
+ a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
30
+ EOT
31
+
32
+ if ONE_LOCATION
33
+ TABLE_CONF_PATH=ONE_LOCATION+"/etc/cli"
34
+ else
35
+ TABLE_CONF_PATH="/etc/one/cli"
36
+ end
37
+
38
+ EDITOR_PATH='/usr/bin/vi'
39
+
40
+ ########################################################################
41
+ # Options
42
+ ########################################################################
43
+ XML={
44
+ :name => "xml",
45
+ :short => "-x",
46
+ :large => "--xml",
47
+ :description => "Show the resource in xml format"
48
+ }
49
+
50
+ NUMERIC={
51
+ :name => "numeric",
52
+ :short => "-n",
53
+ :large => "--numeric",
54
+ :description => "Do not translate user and group IDs"
55
+ }
56
+
57
+ KILOBYTES={
58
+ :name => "kilobytes",
59
+ :short => "-k",
60
+ :large => "--kilobytes",
61
+ :description => "Show units in kilobytes"
62
+ }
63
+
64
+ DESCRIBE={
65
+ :name => "describe",
66
+ :large => "--describe",
67
+ :description => "Describe list columns"
68
+ }
69
+
70
+ # Command line VM template options
71
+ TEMPLATE_NAME_VM={
72
+ :name => 'name',
73
+ :large => '--name name',
74
+ :description =>
75
+ 'Name for the new VM',
76
+ :format => String
77
+ }
78
+
79
+ TEMPLATE_OPTIONS=[
80
+ {
81
+ :name => 'cpu',
82
+ :large => '--cpu cpu',
83
+ :description =>
84
+ 'CPU percentage reserved for the VM (1=100% one CPU)',
85
+ :format => Float
86
+ },
87
+ {
88
+ :name => 'arch',
89
+ :large => '--arch arch',
90
+ :description =>
91
+ 'Architecture of the VM, e.g.: i386 or x86_64',
92
+ :format => String
93
+ },
94
+ {
95
+ :name => 'memory',
96
+ :large => '--memory memory',
97
+ :description => 'Memory ammount given to the VM',
98
+ :format => String,
99
+ :proc => lambda do |o,options|
100
+ m=o.strip.match(/^(\d+(?:\.\d+)?)(m|mb|g|gb)?$/i)
101
+
102
+ if !m
103
+ [-1, 'Memory value malformed']
104
+ else
105
+ multiplier=case m[2]
106
+ when /(g|gb)/i
107
+ 1024
108
+ else
109
+ 1
110
+ end
111
+
112
+ value=m[1].to_f*multiplier
113
+
114
+ [0, value.floor]
115
+ end
116
+ end
117
+ },
118
+ {
119
+ :name => 'disk',
120
+ :large => '--disk disk0,disk1',
121
+ :description => 'Disks to attach. To use a disk owned by other user use user[disk]',
122
+ :format => Array
123
+ },
124
+ {
125
+ :name => 'network',
126
+ :large => '--network network0,network1',
127
+ :description => 'Networks to attach. To use a network owned by other user use user[network]',
128
+ :format => Array
129
+ },
130
+ {
131
+ :name => 'raw',
132
+ :large => '--raw string',
133
+ :description => 'Raw string to add to the template. Not to be confused with the RAW attribute',
134
+ :format => String
135
+ }
136
+ ]
137
+
138
+ TEMPLATE_OPTIONS_VM=[TEMPLATE_NAME_VM]+TEMPLATE_OPTIONS
139
+
140
+ OPTIONS = XML, NUMERIC, KILOBYTES
141
+
142
+ class OneHelper
143
+ def initialize(secret=nil, endpoint=nil)
144
+ begin
145
+ @client = OpenNebula::Client.new(secret,endpoint)
146
+ rescue Exception => e
147
+ puts e.message
148
+ exit -1
149
+ end
150
+
151
+ @translation_hash = nil
152
+ end
153
+
154
+ def create_resource(options, &block)
155
+ resource = factory
156
+
157
+ rc = block.call(resource)
158
+ if OpenNebula.is_error?(rc)
159
+ return -1, rc.message
160
+ else
161
+ puts "ID: #{resource.id.to_s}"
162
+ return 0
163
+ end
164
+ end
165
+
166
+ def list_pool(options, top=false, filter_flag=nil)
167
+ if options[:describe]
168
+ table = format_pool(options)
169
+
170
+ table.describe_columns
171
+ return 0
172
+ end
173
+
174
+ filter_flag ||= OpenNebula::Pool::INFO_ALL
175
+
176
+ pool = factory_pool(filter_flag)
177
+
178
+ rc = pool.info
179
+ return -1, rc.message if OpenNebula.is_error?(rc)
180
+
181
+ if options[:xml]
182
+ return 0, pool.to_xml(true)
183
+ else
184
+ table = format_pool(options)
185
+
186
+ if top
187
+ table.top(options) {
188
+ pool.info
189
+ pool_to_array(pool)
190
+ }
191
+ else
192
+ table.show(pool_to_array(pool), options)
193
+ end
194
+
195
+ return 0
196
+ end
197
+ end
198
+
199
+ def show_resource(id, options)
200
+ resource = retrieve_resource(id)
201
+
202
+ rc = resource.info
203
+ return -1, rc.message if OpenNebula.is_error?(rc)
204
+
205
+ if options[:xml]
206
+ return 0, resource.to_xml(true)
207
+ else
208
+ format_resource(resource)
209
+ return 0
210
+ end
211
+ end
212
+
213
+ def perform_action(id, options, verbose, &block)
214
+ resource = retrieve_resource(id)
215
+
216
+ rc = block.call(resource)
217
+ if OpenNebula.is_error?(rc)
218
+ return -1, rc.message
219
+ else
220
+ if options[:verbose]
221
+ puts "#{self.class.rname} #{id}: #{verbose}"
222
+ end
223
+ return 0
224
+ end
225
+ end
226
+
227
+ def perform_actions(ids,options,verbose,&block)
228
+ exit_code = 0
229
+ ids.each do |id|
230
+ rc = perform_action(id,options,verbose,&block)
231
+
232
+ unless rc[0]==0
233
+ puts rc[1]
234
+ exit_code=rc[0]
235
+ end
236
+ end
237
+
238
+ exit_code
239
+ end
240
+
241
+ ########################################################################
242
+ # Id translation
243
+ ########################################################################
244
+ def user_name(resource, options={})
245
+ if options[:numeric]
246
+ resource['UID']
247
+ else
248
+ resource['UNAME']
249
+ end
250
+ end
251
+
252
+ def group_name(resource, options={})
253
+ if options[:numeric]
254
+ resource['GID']
255
+ else
256
+ resource['GNAME']
257
+ end
258
+ end
259
+
260
+ ########################################################################
261
+ # Formatters for arguments
262
+ ########################################################################
263
+ def to_id(name)
264
+ return 0, name.to_i if name.match(/^[0123456789]+$/)
265
+
266
+ rc = get_pool
267
+ return rc if rc.first != 0
268
+
269
+ pool = rc[1]
270
+ poolname = self.class.rname
271
+
272
+ OneHelper.name_to_id(name, pool, poolname)
273
+ end
274
+
275
+ def self.to_id_desc
276
+ "OpenNebula #{self.rname} name or id"
277
+ end
278
+
279
+ def list_to_id(names)
280
+ rc = get_pool
281
+ return rc if rc.first != 0
282
+
283
+ pool = rc[1]
284
+ poolname = self.class.rname
285
+
286
+ result = names.split(',').collect { |name|
287
+ if name.match(/^[0123456789]+$/)
288
+ name.to_i
289
+ else
290
+ rc = OneHelper.name_to_id(name, pool, poolname)
291
+
292
+ if rc.first == -1
293
+ return rc[0], rc[1]
294
+ end
295
+
296
+ rc[1]
297
+ end
298
+ }
299
+
300
+ return 0, result
301
+ end
302
+
303
+ def self.list_to_id_desc
304
+ "Comma-separated list of OpenNebula #{self.rname} names or ids"
305
+ end
306
+
307
+ def self.name_to_id(name, pool, ename)
308
+ objects=pool.select {|object| object.name==name }
309
+
310
+ if objects.length>0
311
+ if objects.length>1
312
+ return -1, "There are multiple #{ename}s with name #{name}."
313
+ else
314
+ result = objects.first.id
315
+ end
316
+ else
317
+ return -1, "#{ename} named #{name} not found."
318
+ end
319
+
320
+ return 0, result
321
+ end
322
+
323
+ def filterflag_to_i(str)
324
+ filter_flag = case str
325
+ when "a", "all" then OpenNebula::Pool::INFO_ALL
326
+ when "m", "mine" then OpenNebula::Pool::INFO_MINE
327
+ when "g", "group" then OpenNebula::Pool::INFO_GROUP
328
+ else
329
+ if str.match(/^[0123456789]+$/)
330
+ str.to_i
331
+ else
332
+ rc = OpenNebulaHelper.rname_to_id(str, "USER")
333
+ if rc.first==-1
334
+ return rc
335
+ else
336
+ rc[1]
337
+ end
338
+ end
339
+ end
340
+
341
+ return 0, filter_flag
342
+ end
343
+
344
+ def self.filterflag_to_i_desc
345
+ desc=<<-EOT
346
+ a, all all the known #{self.rname}s
347
+ m, mine the #{self.rname} belonging to the user in ONE_AUTH
348
+ g, group 'mine' plus the #{self.rname} belonging to the groups
349
+ the user is member of
350
+ uid #{self.rname} of the user identified by this uid
351
+ user #{self.rname} of the user identified by the username
352
+ EOT
353
+ end
354
+
355
+ def self.table_conf
356
+ path = "#{ENV["HOME"]}/.one/cli/#{self.conf_file}"
357
+
358
+ if File.exists?(path)
359
+ return path
360
+ else
361
+ return "#{TABLE_CONF_PATH}/#{self.conf_file}"
362
+ end
363
+ end
364
+
365
+ private
366
+
367
+ def retrieve_resource(id)
368
+ factory(id)
369
+ end
370
+
371
+ def pool_to_array(pool)
372
+ if !pool.instance_of?(Hash)
373
+ phash = pool.to_hash
374
+ else
375
+ phash = pool
376
+ end
377
+
378
+ rname = self.class.rname
379
+
380
+ if phash["#{rname}_POOL"] &&
381
+ phash["#{rname}_POOL"]["#{rname}"]
382
+ if phash["#{rname}_POOL"]["#{rname}"].instance_of?(Array)
383
+ phash = phash["#{rname}_POOL"]["#{rname}"]
384
+ else
385
+ phash = [phash["#{rname}_POOL"]["#{rname}"]]
386
+ end
387
+ else
388
+ phash = Array.new
389
+ end
390
+
391
+ phash
392
+ end
393
+
394
+ def get_pool
395
+ user_flag = OpenNebula::Pool::INFO_ALL
396
+ pool = factory_pool(user_flag)
397
+
398
+ rc = pool.info
399
+ if OpenNebula.is_error?(rc)
400
+ return -1, "OpenNebula #{self.class.rname} name not " <<
401
+ "found, use the ID instead"
402
+ end
403
+
404
+ return 0, pool
405
+ end
406
+ end
407
+
408
+ def OpenNebulaHelper.rname_to_id(name, poolname)
409
+ return 0, name.to_i if name.match(/^[0123456789]+$/)
410
+
411
+ client = OpenNebula::Client.new
412
+
413
+ pool = case poolname
414
+ when "HOST" then OpenNebula::HostPool.new(client)
415
+ when "GROUP" then OpenNebula::GroupPool.new(client)
416
+ when "USER" then OpenNebula::UserPool.new(client)
417
+ when "DATASTORE" then OpenNebula::DatastorePool.new(client)
418
+ when "CLUSTER" then OpenNebula::ClusterPool.new(client)
419
+ when "VNET" then OpenNebula::VirtualNetworkPool.new(client)
420
+ when "IMAGE" then OpenNebula::ImagePool.new(client)
421
+ when "VMTEMPLATE" then OpenNebula::TemplatePool.new(client)
422
+ when "VM" then OpenNebula::VirtualMachinePool.new(client)
423
+ end
424
+
425
+ rc = pool.info
426
+ if OpenNebula.is_error?(rc)
427
+ return -1, "OpenNebula #{poolname} name not found," <<
428
+ " use the ID instead"
429
+ end
430
+
431
+ OneHelper.name_to_id(name, pool, poolname)
432
+ end
433
+
434
+ def OpenNebulaHelper.rname_to_id_desc(poolname)
435
+ "OpenNebula #{poolname} name or id"
436
+ end
437
+
438
+ def OpenNebulaHelper.boolean_to_str(str)
439
+ if str.to_i == 1
440
+ "Yes"
441
+ else
442
+ "No"
443
+ end
444
+ end
445
+
446
+ def OpenNebulaHelper.time_to_str(time)
447
+ value=time.to_i
448
+ if value==0
449
+ value='-'
450
+ else
451
+ value=Time.at(value).strftime("%m/%d %H:%M:%S")
452
+ end
453
+ end
454
+
455
+ def OpenNebulaHelper.period_to_str(time, print_seconds=true)
456
+ seconds=time.to_i
457
+ minutes, seconds=seconds.divmod(60)
458
+ hours, minutes=minutes.divmod(60)
459
+ days, hours=hours.divmod(24)
460
+
461
+ if print_seconds
462
+ "%3dd %02dh%02dm%02ds" % [days, hours, minutes, seconds]
463
+ else
464
+ "%3dd %02dh%02dm" % [days, hours, minutes]
465
+ end
466
+ end
467
+
468
+ BinarySufix = ["K", "M", "G", "T" ]
469
+
470
+ def OpenNebulaHelper.unit_to_str(value, options, unit="K")
471
+ if options[:kilobytes]
472
+ value
473
+ else
474
+ i=BinarySufix.index(unit).to_i
475
+
476
+ while value > 1024 && i < 3 do
477
+ value /= 1024.0
478
+ i+=1
479
+ end
480
+
481
+ value = (value * 10).round / 10.0
482
+
483
+ value = value.to_i if value - value.round == 0
484
+ st = value.to_s + BinarySufix[i]
485
+ end
486
+ end
487
+
488
+ # If the cluster name is empty, returns a '-' char.
489
+ #
490
+ # @param str [String || Hash] Cluster name, or empty Hash (when <CLUSTER/>)
491
+ # @return [String] the same Cluster name, or '-' if it is empty
492
+ def OpenNebulaHelper.cluster_str(str)
493
+ if str != nil && !str.empty?
494
+ str
495
+ else
496
+ "-"
497
+ end
498
+ end
499
+
500
+ def OpenNebulaHelper.update_template(id, resource, path=nil)
501
+ unless path
502
+ require 'tempfile'
503
+
504
+ tmp = Tempfile.new(id.to_s)
505
+ path = tmp.path
506
+
507
+ rc = resource.info
508
+
509
+ if OpenNebula.is_error?(rc)
510
+ puts rc.message
511
+ exit -1
512
+ end
513
+
514
+ tmp << resource.template_str
515
+ tmp.flush
516
+
517
+ editor_path = ENV["EDITOR"] ? ENV["EDITOR"] : EDITOR_PATH
518
+ system("#{editor_path} #{path}")
519
+
520
+ unless $?.exitstatus == 0
521
+ puts "Editor not defined"
522
+ exit -1
523
+ end
524
+
525
+ tmp.close
526
+ end
527
+
528
+ str = File.read(path)
529
+ str
530
+ end
531
+
532
+ def self.parse_user_object(user_object)
533
+ reg=/^([^\[]+)(?:\[([^\]]+)\])?$/
534
+
535
+ m=user_object.match(reg)
536
+
537
+ return nil if !m
538
+
539
+ user=nil
540
+ if m[2]
541
+ user=m[1]
542
+ object=m[2]
543
+ else
544
+ object=m[1]
545
+ end
546
+
547
+ [user, object]
548
+ end
549
+
550
+ def self.create_disk_net(objects, section, name)
551
+ template=''
552
+
553
+ objects.each do |obj|
554
+ res=parse_user_object(obj)
555
+ return [-1, "#{section.capitalize} \"#{obj}\" malformed"] if !res
556
+ user, object=*res
557
+
558
+ template<<"#{section.upcase}=[\n"
559
+ template<<" #{name.upcase}_UNAME=\"#{user}\",\n" if user
560
+ if object.match(/^\d$/)
561
+ template<<" #{name.upcase}_ID=#{object}\n"
562
+ else
563
+ template<<" #{name.upcase}=\"#{object}\"\n"
564
+ end
565
+ template<<"]\n"
566
+ end if objects
567
+
568
+ [0, template]
569
+ end
570
+
571
+ def self.create_template(options)
572
+ template=''
573
+
574
+ template<<"NAME=\"#{options[:name]}\"\n" if options[:name]
575
+ template<<"OS = [ ARCH = \"#{options[:arch]}\" ]\n" if options[:arch]
576
+ template<<"CPU=#{options[:cpu]}\n" if options[:cpu]
577
+ template<<"MEMORY=#{options[:memory]}\n" if options[:memory]
578
+ template<<"#{options[:raw]}\n" if options[:raw]
579
+
580
+ if options[:disk]
581
+ res=create_disk_net(options[:disk], 'DISK', 'IMAGE')
582
+ return res if res.first!=0
583
+
584
+ template<<res.last
585
+ end
586
+
587
+ if options[:network]
588
+ res=create_disk_net(options[:network], 'NIC', 'NETWORK')
589
+ return res if res.first!=0
590
+
591
+ template<<res.last
592
+ end
593
+
594
+
595
+ [0, template]
596
+ end
597
+
598
+ def self.create_template_options_used?(options)
599
+ # Get the template options names as symbols. options hash
600
+ # uses symbols
601
+ template_options=OpenNebulaHelper::TEMPLATE_OPTIONS.map do |o|
602
+ o[:name].to_sym
603
+ end
604
+
605
+ # Check if one at least one of the template options is
606
+ # in options hash
607
+ (template_options-options.keys)!=template_options
608
+ end
609
+ end