rvc 1.5.0 → 1.6.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README.rdoc +1 -1
- data/Rakefile +2 -1
- data/VERSION +1 -1
- data/bin/rvc +53 -9
- data/lib/rvc/completion.rb +57 -19
- data/lib/rvc/extensions/ComputeResource.rb +2 -2
- data/lib/rvc/extensions/DVPortSetting.rb +108 -0
- data/lib/rvc/extensions/Datacenter.rb +19 -4
- data/lib/rvc/extensions/Datastore.rb +6 -1
- data/lib/rvc/extensions/DistributedVirtualPort.rb +146 -0
- data/lib/rvc/extensions/DistributedVirtualPortgroup.rb +274 -10
- data/lib/rvc/extensions/DistributedVirtualSwitch.rb +124 -3
- data/lib/rvc/extensions/Folder.rb +9 -2
- data/lib/rvc/extensions/HostSystem.rb +60 -0
- data/lib/rvc/extensions/ManagedEntity.rb +19 -0
- data/lib/rvc/extensions/ParaVirtualSCSIController.rb +25 -0
- data/lib/rvc/extensions/PerfCounterInfo.rb +26 -0
- data/lib/rvc/extensions/PerformanceManager.rb +83 -0
- data/lib/rvc/extensions/ResourcePool.rb +21 -0
- data/lib/rvc/extensions/VirtualDevice.rb +59 -0
- data/lib/rvc/extensions/VirtualDisk.rb +25 -0
- data/lib/rvc/extensions/VirtualEthernetCard.rb +32 -0
- data/lib/rvc/extensions/VirtualMachine.rb +112 -1
- data/lib/rvc/field.rb +122 -0
- data/lib/rvc/filesystem_session.rb +20 -0
- data/lib/rvc/inventory.rb +35 -12
- data/lib/rvc/known_hosts.rb +20 -0
- data/lib/rvc/memory_session.rb +20 -0
- data/lib/rvc/modules.rb +67 -7
- data/lib/rvc/modules/alarm.rb +37 -0
- data/lib/rvc/modules/basic.rb +172 -41
- data/lib/rvc/modules/cluster.rb +18 -2
- data/lib/rvc/modules/core.rb +63 -0
- data/lib/rvc/modules/datastore.rb +158 -0
- data/lib/rvc/modules/device.rb +275 -0
- data/lib/rvc/modules/esxcli.rb +193 -0
- data/lib/rvc/modules/find.rb +125 -0
- data/lib/rvc/modules/issue.rb +33 -0
- data/lib/rvc/modules/perf.rb +284 -0
- data/lib/rvc/modules/permissions.rb +20 -0
- data/lib/rvc/modules/resource_pool.rb +69 -0
- data/lib/rvc/modules/role.rb +23 -3
- data/lib/rvc/modules/snapshot.rb +20 -0
- data/lib/rvc/modules/vds.rb +605 -0
- data/lib/rvc/modules/vim.rb +103 -26
- data/lib/rvc/modules/vm.rb +93 -220
- data/lib/rvc/modules/vnc.rb +50 -13
- data/lib/rvc/option_parser.rb +50 -2
- data/lib/rvc/readline-ffi.rb +2 -1
- data/lib/rvc/shell.rb +34 -33
- data/lib/rvc/util.rb +120 -2
- data/test/test_fs.rb +9 -5
- data/test/test_metric.rb +79 -0
- metadata +33 -3
@@ -31,10 +31,34 @@ class RbVmomi::VIM::HostSystem
|
|
31
31
|
" (host): cpu #{numCpuPkgs}*#{numCpuCores}*#{"%.2f" % (cpuMhz.to_f/1000)} GHz, memory #{"%.2f" % (memorySize/10**9)} GB"
|
32
32
|
end
|
33
33
|
|
34
|
+
def display_info
|
35
|
+
summary = self.summary
|
36
|
+
runtime = summary.runtime
|
37
|
+
stats = summary.quickStats
|
38
|
+
hw = summary.hardware
|
39
|
+
puts "connection state: #{runtime.connectionState}"
|
40
|
+
puts "power state: #{runtime.powerState}"
|
41
|
+
puts "uptime: #{"%0.2f" % ((Time.now - runtime.bootTime)/(24*3600))} days" if runtime.bootTime
|
42
|
+
puts "in maintenance mode: #{runtime.inMaintenanceMode}"
|
43
|
+
puts "standby mode: #{runtime.standbyMode}" if runtime.standbyMode
|
44
|
+
if about = summary.config.product
|
45
|
+
puts "product: #{about.fullName}"
|
46
|
+
puts "license: #{about.licenseProductName} #{about.licenseProductVersion}" if about.licenseProductName
|
47
|
+
end
|
48
|
+
if runtime.connectionState == 'connected' and runtime.powerState == 'poweredOn'
|
49
|
+
overallCpu = hw.numCpuPkgs * hw.numCpuCores * hw.cpuMhz
|
50
|
+
puts "cpu: %d*%d*%.2f GHz = %.2f GHz" % [hw.numCpuPkgs, hw.numCpuCores, hw.cpuMhz/1e3, overallCpu/1e3]
|
51
|
+
puts "cpu usage: %.2f GHz (%.1f%%)" % [stats.overallCpuUsage/1e3, 100*stats.overallCpuUsage/overallCpu]
|
52
|
+
puts "memory: %.2f GB" % [hw.memorySize/1e9]
|
53
|
+
puts "memory usage: %.2f GB (%.1f%%)" % [stats.overallMemoryUsage/1e3, 100*1e6*stats.overallMemoryUsage/hw.memorySize]
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
34
57
|
def children
|
35
58
|
{
|
36
59
|
'vms' => RVC::FakeFolder.new(self, :ls_vms),
|
37
60
|
'datastores' => RVC::FakeFolder.new(self, :ls_datastores),
|
61
|
+
'networks' => RVC::FakeFolder.new(self, :ls_networks),
|
38
62
|
}
|
39
63
|
end
|
40
64
|
|
@@ -45,4 +69,40 @@ class RbVmomi::VIM::HostSystem
|
|
45
69
|
def ls_datastores
|
46
70
|
RVC::Util.collect_children self, :datastore
|
47
71
|
end
|
72
|
+
|
73
|
+
def ls_networks
|
74
|
+
RVC::Util.collect_children self, :network
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
class VIM::EsxcliCommand
|
79
|
+
def option_parser
|
80
|
+
parser = Trollop::Parser.new
|
81
|
+
parser.text cli_info.help
|
82
|
+
cli_info.param.each do |cli_param|
|
83
|
+
vmodl_param = type_info.paramTypeInfo.find { |x| x.name == cli_param.name }
|
84
|
+
opts = trollop_type(vmodl_param.type)
|
85
|
+
opts[:required] = vmodl_param.annotation.find { |a| a.name == "optional"} ? false : true
|
86
|
+
opts[:long] = cli_param.displayName
|
87
|
+
#pp opts.merge(:name => cli_param.name)
|
88
|
+
# XXX correct short options
|
89
|
+
parser.opt cli_param.name, cli_param.help, opts
|
90
|
+
end
|
91
|
+
parser
|
92
|
+
end
|
93
|
+
|
94
|
+
def trollop_type t
|
95
|
+
if t[-2..-1] == '[]'
|
96
|
+
multi = true
|
97
|
+
t = t[0...-2]
|
98
|
+
else
|
99
|
+
multi = false
|
100
|
+
end
|
101
|
+
type = case t
|
102
|
+
when 'string', 'boolean' then t.to_sym
|
103
|
+
when 'long' then :int
|
104
|
+
else fail "unexpected esxcli type #{t.inspect}"
|
105
|
+
end
|
106
|
+
{ :type => type, :multi => multi }
|
107
|
+
end
|
48
108
|
end
|
@@ -21,6 +21,25 @@
|
|
21
21
|
class RbVmomi::VIM::ManagedEntity
|
22
22
|
include RVC::InventoryObject
|
23
23
|
|
24
|
+
field 'name' do
|
25
|
+
summary "Name"
|
26
|
+
property 'name'
|
27
|
+
default
|
28
|
+
end
|
29
|
+
|
30
|
+
field 'status' do
|
31
|
+
summary 'Status (green/yellow/red/gray)'
|
32
|
+
property 'overallStatus'
|
33
|
+
default
|
34
|
+
end
|
35
|
+
|
36
|
+
STATUS_COLORS = {
|
37
|
+
'gray' => [],
|
38
|
+
'red' => [:red],
|
39
|
+
'green' => [],
|
40
|
+
'yellow' => [:yellow],
|
41
|
+
}
|
42
|
+
|
24
43
|
def display_info
|
25
44
|
puts "name: #{name}"
|
26
45
|
puts "type: #{self.class.name}"
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# Copyright (c) 2011 VMware, Inc. All Rights Reserved.
|
2
|
+
#
|
3
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
4
|
+
# of this software and associated documentation files (the "Software"), to deal
|
5
|
+
# in the Software without restriction, including without limitation the rights
|
6
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
7
|
+
# copies of the Software, and to permit persons to whom the Software is
|
8
|
+
# furnished to do so, subject to the following conditions:
|
9
|
+
#
|
10
|
+
# The above copyright notice and this permission notice shall be included in
|
11
|
+
# all copies or substantial portions of the Software.
|
12
|
+
#
|
13
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
14
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
15
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
16
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
17
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
18
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
19
|
+
# THE SOFTWARE.
|
20
|
+
|
21
|
+
class RbVmomi::VIM::ParaVirtualSCSIController
|
22
|
+
def name
|
23
|
+
"pvscsi-#{key}"
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# Copyright (c) 2011 VMware, Inc. All Rights Reserved.
|
2
|
+
#
|
3
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
4
|
+
# of this software and associated documentation files (the "Software"), to deal
|
5
|
+
# in the Software without restriction, including without limitation the rights
|
6
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
7
|
+
# copies of the Software, and to permit persons to whom the Software is
|
8
|
+
# furnished to do so, subject to the following conditions:
|
9
|
+
#
|
10
|
+
# The above copyright notice and this permission notice shall be included in
|
11
|
+
# all copies or substantial portions of the Software.
|
12
|
+
#
|
13
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
14
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
15
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
16
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
17
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
18
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
19
|
+
# THE SOFTWARE.
|
20
|
+
|
21
|
+
class RbVmomi::VIM::PerfCounterInfo
|
22
|
+
def name
|
23
|
+
"#{groupInfo.key}.#{nameInfo.key}.#{rollupType}"
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
@@ -0,0 +1,83 @@
|
|
1
|
+
require 'date'
|
2
|
+
|
3
|
+
class Time
|
4
|
+
def to_datetime
|
5
|
+
# Convert seconds + microseconds into a fractional number of seconds
|
6
|
+
seconds = sec + Rational(usec, 10**6)
|
7
|
+
|
8
|
+
# Convert a UTC offset measured in minutes to one measured in a
|
9
|
+
# fraction of a day.
|
10
|
+
offset = Rational(utc_offset, 60 * 60 * 24)
|
11
|
+
DateTime.new(year, month, day, hour, min, seconds, offset)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
RbVmomi::VIM::PerfCounterInfo
|
16
|
+
class RbVmomi::VIM::PerfCounterInfo
|
17
|
+
def pretty_name
|
18
|
+
@pretty_name ||= "#{self.groupInfo.key}.#{self.nameInfo.key}.#{self.rollupType}"
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
RbVmomi::VIM::PerformanceManager
|
23
|
+
class RbVmomi::VIM::PerformanceManager
|
24
|
+
def perfcounter_cached
|
25
|
+
@perfcounter ||= perfCounter
|
26
|
+
end
|
27
|
+
|
28
|
+
def perfcounter_hash
|
29
|
+
@perfcounter_hash ||= Hash[perfcounter_cached.map{|x| [x.pretty_name, x]}]
|
30
|
+
end
|
31
|
+
|
32
|
+
def perfcounter_idhash
|
33
|
+
@perfcounter_idhash ||= Hash[perfcounter_cached.map{|x| [x.key, x]}]
|
34
|
+
end
|
35
|
+
|
36
|
+
def provider_summary obj
|
37
|
+
@provider_summary ||= {}
|
38
|
+
@provider_summary[obj.class] ||= QueryPerfProviderSummary(:entity => obj)
|
39
|
+
end
|
40
|
+
|
41
|
+
def retrieve_stats objects, metrics, opts = {}
|
42
|
+
opts = opts.dup
|
43
|
+
max_samples = opts[:max_samples] || 1
|
44
|
+
realtime = false
|
45
|
+
if not opts[:interval]
|
46
|
+
provider = provider_summary objects.first
|
47
|
+
opts[:interval] = provider.refreshRate
|
48
|
+
realtime = true
|
49
|
+
else
|
50
|
+
provider = provider_summary objects.first
|
51
|
+
if opts[:interval] == provider.refreshRate
|
52
|
+
realtime = true
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
metric_ids = metrics.map do |x|
|
57
|
+
RbVmomi::VIM::PerfMetricId(:counterId => perfcounter_hash[x].key, :instance => '*')
|
58
|
+
end
|
59
|
+
query_specs = objects.map do |obj|
|
60
|
+
RbVmomi::VIM::PerfQuerySpec({
|
61
|
+
:maxSample => max_samples,
|
62
|
+
:entity => obj,
|
63
|
+
:metricId => metric_ids,
|
64
|
+
:intervalId => opts[:interval],
|
65
|
+
:startTime => (realtime == false ? opts[:start_time].to_datetime : nil),
|
66
|
+
})
|
67
|
+
end
|
68
|
+
stats = QueryPerf(:querySpec => query_specs)
|
69
|
+
|
70
|
+
Hash[stats.map do |res|
|
71
|
+
[
|
72
|
+
res.entity,
|
73
|
+
{
|
74
|
+
:sampleInfo => res.sampleInfo,
|
75
|
+
:metrics => Hash[res.value.map do |metric|
|
76
|
+
[perfcounter_idhash[metric.id.counterId].pretty_name, metric.value]
|
77
|
+
end]
|
78
|
+
}
|
79
|
+
]
|
80
|
+
end]
|
81
|
+
end
|
82
|
+
|
83
|
+
end
|
@@ -35,6 +35,27 @@ class RbVmomi::VIM::ResourcePool
|
|
35
35
|
]
|
36
36
|
end
|
37
37
|
|
38
|
+
def display_info
|
39
|
+
cfg = config
|
40
|
+
rt = runtime
|
41
|
+
cpuAlloc, memAlloc = cfg.cpuAllocation, cfg.memoryAllocation
|
42
|
+
|
43
|
+
|
44
|
+
cpu_shares_text = cpuAlloc.shares.level == 'custom' ? cpuAlloc.shares.shares.to_s : cpuAlloc.shares.level
|
45
|
+
mem_shares_text = memAlloc.shares.level == 'custom' ? memAlloc.shares.shares.to_s : memAlloc.shares.level
|
46
|
+
|
47
|
+
puts "cpu:"
|
48
|
+
puts " reservation: %0.2f GHz" % [cpuAlloc.reservation/1e3]
|
49
|
+
puts " limit: %0.2f GHz" % [cpuAlloc.limit/1e3]
|
50
|
+
puts " shares: #{cpu_shares_text}"
|
51
|
+
puts " usage: %0.2f Ghz (%0.1f)%%" % [rt.cpu.overallUsage/1e3, 100.0*rt.cpu.overallUsage/rt.cpu.maxUsage]
|
52
|
+
puts "memory:"
|
53
|
+
puts " reservation: %0.2f GB" % [memAlloc.reservation/1e3]
|
54
|
+
puts " limit: %0.2f GB" % [memAlloc.limit/1e3]
|
55
|
+
puts " shares: #{mem_shares_text}"
|
56
|
+
puts " usage: %0.2f GB (%0.1f)%%" % [rt.memory.overallUsage/1e9, 100.0*rt.memory.overallUsage/rt.memory.maxUsage]
|
57
|
+
end
|
58
|
+
|
38
59
|
def children
|
39
60
|
{
|
40
61
|
'vms' => RVC::FakeFolder.new(self, :children_vms),
|
@@ -0,0 +1,59 @@
|
|
1
|
+
# Copyright (c) 2011 VMware, Inc. All Rights Reserved.
|
2
|
+
#
|
3
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
4
|
+
# of this software and associated documentation files (the "Software"), to deal
|
5
|
+
# in the Software without restriction, including without limitation the rights
|
6
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
7
|
+
# copies of the Software, and to permit persons to whom the Software is
|
8
|
+
# furnished to do so, subject to the following conditions:
|
9
|
+
#
|
10
|
+
# The above copyright notice and this permission notice shall be included in
|
11
|
+
# all copies or substantial portions of the Software.
|
12
|
+
#
|
13
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
14
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
15
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
16
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
17
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
18
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
19
|
+
# THE SOFTWARE.
|
20
|
+
|
21
|
+
class RbVmomi::VIM::VirtualDevice
|
22
|
+
include RVC::InventoryObject
|
23
|
+
attr_accessor :rvc_vm
|
24
|
+
|
25
|
+
# Stable name based on the device key, unit number, etc.
|
26
|
+
# May be overridden in subclasses.
|
27
|
+
def name
|
28
|
+
self.class.to_s =~ /^(?:Virtual)?(?:Machine)?(\w+?)(?:Card|Device|Controller)?$/
|
29
|
+
type = $1 ? $1.downcase : 'device'
|
30
|
+
"#{type}-#{key}"
|
31
|
+
end
|
32
|
+
|
33
|
+
def ls_text r
|
34
|
+
tags = []
|
35
|
+
tags << (connectable.connected ? :connected : :disconnected) if props.member? :connectable
|
36
|
+
" (#{self.class}): #{deviceInfo.summary}; #{tags * ' '}"
|
37
|
+
end
|
38
|
+
|
39
|
+
def display_info
|
40
|
+
super
|
41
|
+
devices, = rvc_vm.collect 'config.hardware.device'
|
42
|
+
puts "label: #{deviceInfo.label}"
|
43
|
+
puts "summary: #{deviceInfo.summary}"
|
44
|
+
puts "key: #{key}"
|
45
|
+
if controllerKey
|
46
|
+
controller = devices.find { |x| x.key == controllerKey }
|
47
|
+
puts "controller: #{controller.name}" if controller
|
48
|
+
end
|
49
|
+
puts "unit number: #{unitNumber}" if unitNumber
|
50
|
+
if connectable
|
51
|
+
puts "connectivity:"
|
52
|
+
puts " connected: #{connectable.connected}"
|
53
|
+
puts " start connected: #{connectable.startConnected}"
|
54
|
+
puts " guest control: #{connectable.allowGuestControl}"
|
55
|
+
puts " status: #{connectable.status}"
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# Copyright (c) 2011 VMware, Inc. All Rights Reserved.
|
2
|
+
#
|
3
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
4
|
+
# of this software and associated documentation files (the "Software"), to deal
|
5
|
+
# in the Software without restriction, including without limitation the rights
|
6
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
7
|
+
# copies of the Software, and to permit persons to whom the Software is
|
8
|
+
# furnished to do so, subject to the following conditions:
|
9
|
+
#
|
10
|
+
# The above copyright notice and this permission notice shall be included in
|
11
|
+
# all copies or substantial portions of the Software.
|
12
|
+
#
|
13
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
14
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
15
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
16
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
17
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
18
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
19
|
+
# THE SOFTWARE.
|
20
|
+
|
21
|
+
class RbVmomi::VIM::VirtualDisk
|
22
|
+
def name
|
23
|
+
"disk-#{controllerKey}-#{unitNumber}"
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
# Copyright (c) 2011 VMware, Inc. All Rights Reserved.
|
2
|
+
#
|
3
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
4
|
+
# of this software and associated documentation files (the "Software"), to deal
|
5
|
+
# in the Software without restriction, including without limitation the rights
|
6
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
7
|
+
# copies of the Software, and to permit persons to whom the Software is
|
8
|
+
# furnished to do so, subject to the following conditions:
|
9
|
+
#
|
10
|
+
# The above copyright notice and this permission notice shall be included in
|
11
|
+
# all copies or substantial portions of the Software.
|
12
|
+
#
|
13
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
14
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
15
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
16
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
17
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
18
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
19
|
+
# THE SOFTWARE.
|
20
|
+
|
21
|
+
class RbVmomi::VIM::VirtualEthernetCard
|
22
|
+
def display_info
|
23
|
+
super
|
24
|
+
puts "address type: #{addressType}"
|
25
|
+
puts "MAC address: #{macAddress}"
|
26
|
+
puts "Wake on LAN enabled: #{wakeOnLanEnabled}"
|
27
|
+
end
|
28
|
+
|
29
|
+
def name
|
30
|
+
"ethernet-#{unitNumber-7}"
|
31
|
+
end
|
32
|
+
end
|
@@ -19,6 +19,105 @@
|
|
19
19
|
# THE SOFTWARE.
|
20
20
|
|
21
21
|
class RbVmomi::VIM::VirtualMachine
|
22
|
+
field 'on' do
|
23
|
+
summary "Is the VM powered on?"
|
24
|
+
properties %w(runtime.powerState)
|
25
|
+
block { |powerState| powerState == 'poweredOn' }
|
26
|
+
default
|
27
|
+
end
|
28
|
+
|
29
|
+
field 'storagebw' do
|
30
|
+
summary "Storage Bandwidth"
|
31
|
+
perfmetrics %w(disk.read.average disk.write.average)
|
32
|
+
block do |read, write|
|
33
|
+
if read && write
|
34
|
+
io = (read.sum.to_f / read.length) + (write.sum.to_f / write.length)
|
35
|
+
MetricNumber.new(io * 1024, 'B/s')
|
36
|
+
else
|
37
|
+
nil
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
[['', 5], ['.realtime', 1], ['.5min', 5 * 3], ['.10min', 10 * 3]].each do |label, max_samples|
|
43
|
+
field "storageiops#{label}" do
|
44
|
+
summary "Storage IOPS"
|
45
|
+
perfmetrics %w(disk.numberReadAveraged.average disk.numberWriteAveraged.average)
|
46
|
+
perfmetric_settings :max_samples => max_samples
|
47
|
+
block do |read, write|
|
48
|
+
if read && write
|
49
|
+
io = (read.sum.to_f / read.length) + (write.sum.to_f / write.length)
|
50
|
+
MetricNumber.new(io, 'IOPS')
|
51
|
+
else
|
52
|
+
nil
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
field 'ip' do
|
59
|
+
summary "The guest tools reported IP address."
|
60
|
+
property 'guest.ipAddress'
|
61
|
+
end
|
62
|
+
|
63
|
+
field 'template' do
|
64
|
+
summary "Is this VM a template?"
|
65
|
+
property 'config.template'
|
66
|
+
end
|
67
|
+
|
68
|
+
field 'uptime' do
|
69
|
+
summary "VM's uptime in seconds"
|
70
|
+
properties %w(runtime.bootTime)
|
71
|
+
block { |t| t ? TimeDiff.new(Time.now-t) : nil }
|
72
|
+
end
|
73
|
+
|
74
|
+
field 'storage.used' do
|
75
|
+
summary "Total storage used"
|
76
|
+
properties %w(storage)
|
77
|
+
block do |storage|
|
78
|
+
MetricNumber.new(storage.perDatastoreUsage.map(&:committed).sum, 'B')
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
field 'storage.unshared' do
|
83
|
+
summary "Total storage unshared"
|
84
|
+
properties %w(storage)
|
85
|
+
block do |storage|
|
86
|
+
MetricNumber.new(storage.perDatastoreUsage.map(&:unshared).sum, 'B')
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
field 'storage.provisioned' do
|
91
|
+
summary "Total storage provisioned"
|
92
|
+
properties %w(storage)
|
93
|
+
block do |storage|
|
94
|
+
MetricNumber.new(storage.perDatastoreUsage.map { |x| x.uncommitted + x.committed }.sum, 'B')
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
field 'guest.id' do
|
99
|
+
summary 'Guest OS identifier'
|
100
|
+
property 'summary.config.guestId'
|
101
|
+
end
|
102
|
+
|
103
|
+
field 'tools.running' do
|
104
|
+
summary 'Are guest tools running?'
|
105
|
+
properties %w(guest.toolsRunningStatus)
|
106
|
+
block { |status| status == 'guestToolsRunning' }
|
107
|
+
end
|
108
|
+
|
109
|
+
field 'tools.uptodate' do
|
110
|
+
summary "Are guest tools up to date?"
|
111
|
+
properties %w(guest.toolsVersionStatus)
|
112
|
+
block { |status| status == 'guestToolsCurrent' }
|
113
|
+
end
|
114
|
+
|
115
|
+
field 'mac' do
|
116
|
+
summary "Mac address"
|
117
|
+
properties %w(config.hardware)
|
118
|
+
block { |hw| hw.device.grep(VIM::VirtualEthernetCard).map(&:macAddress) }
|
119
|
+
end
|
120
|
+
|
22
121
|
def display_info
|
23
122
|
config, runtime, guest = collect :config, :runtime, :guest
|
24
123
|
RVC::Util.err "Information currently unavailable" unless config and runtime and guest
|
@@ -51,7 +150,12 @@ class RbVmomi::VIM::VirtualMachine
|
|
51
150
|
dev.backing.class.name
|
52
151
|
end
|
53
152
|
guest_net = guest.net.find { |x| x.macAddress == dev.macAddress }
|
54
|
-
puts " #{dev.
|
153
|
+
puts " #{dev.name}: #{backing_info} #{dev.connectable.connected ? :connected : :disconnected} #{dev.macAddress} #{guest_net ? (guest_net.ipAddress * ' ') : ''}"
|
154
|
+
end
|
155
|
+
|
156
|
+
puts "storage:"
|
157
|
+
storage.perDatastoreUsage.map do |usage|
|
158
|
+
puts " #{usage.datastore.name}: committed=#{usage.committed.metric}B uncommitted=#{usage.uncommitted.metric}B unshared=#{usage.unshared.metric}B"
|
55
159
|
end
|
56
160
|
end
|
57
161
|
|
@@ -72,6 +176,7 @@ class RbVmomi::VIM::VirtualMachine
|
|
72
176
|
'networks' => RVC::FakeFolder.new(self, :rvc_children_networks),
|
73
177
|
'files' => RVC::FakeFolder.new(self, :rvc_children_files),
|
74
178
|
'snapshots' => RVC::RootSnapshotFolder.new(self),
|
179
|
+
'devices' => RVC::FakeFolder.new(self, :rvc_children_devices),
|
75
180
|
}
|
76
181
|
end
|
77
182
|
|
@@ -96,6 +201,12 @@ class RbVmomi::VIM::VirtualMachine
|
|
96
201
|
[File.basename(file.name), objs.first]
|
97
202
|
end]
|
98
203
|
end
|
204
|
+
|
205
|
+
def rvc_children_devices
|
206
|
+
devices, = collect 'config.hardware.device'
|
207
|
+
devices.each { |x| x.rvc_vm = self }
|
208
|
+
Hash[devices.map { |x| [x.name, x] }]
|
209
|
+
end
|
99
210
|
end
|
100
211
|
|
101
212
|
class RVC::RootSnapshotFolder
|