mirror of
https://github.com/OpenNebula/one.git
synced 2025-01-27 14:03:40 +03:00
Update vendorized rbvmomi to version 1.8.2
This commit is contained in:
parent
8474dd89a5
commit
1fb5f9aeff
2
share/vendor/ruby/gems/rbvmomi/Rakefile
vendored
2
share/vendor/ruby/gems/rbvmomi/Rakefile
vendored
@ -1,5 +1,5 @@
|
||||
require 'rake/testtask'
|
||||
require 'rake/rdoctask'
|
||||
require 'rdoc/task'
|
||||
require 'yard'
|
||||
|
||||
begin
|
||||
|
2
share/vendor/ruby/gems/rbvmomi/VERSION
vendored
2
share/vendor/ruby/gems/rbvmomi/VERSION
vendored
@ -1 +1 @@
|
||||
1.6.0
|
||||
1.8.2
|
||||
|
@ -185,7 +185,9 @@ class ManagedObject < ObjectWithMethods
|
||||
:objectSet => [{ :obj => self }],
|
||||
}])[0]
|
||||
|
||||
if ret.propSet.empty?
|
||||
if !ret
|
||||
return nil
|
||||
elsif ret.propSet.empty?
|
||||
return nil if ret.missingSet.empty?
|
||||
raise ret.missingSet[0].fault
|
||||
else
|
||||
@ -217,7 +219,7 @@ class ManagedObject < ObjectWithMethods
|
||||
|
||||
def == x
|
||||
out = (x.class == self.class && x._ref == @ref)
|
||||
out = (out && x._connection.instanceUuid == self._connection.instanceUuid)
|
||||
out = (x._connection.instanceUuid == self._connection.instanceUuid) if out && x._connection.host
|
||||
out
|
||||
end
|
||||
|
||||
|
@ -115,27 +115,29 @@ class Connection < TrivialSoap
|
||||
# hic sunt dracones
|
||||
def obj2xml xml, name, type, is_array, o, attrs={}
|
||||
expected = type(type)
|
||||
fail "expected array, got #{o.class.wsdl_name}" if is_array and not (o.is_a? Array or (o.is_a? Hash and expected == BasicTypes::KeyValue))
|
||||
fail "expected array for '#{name}', got #{o.class.wsdl_name}" if is_array and not (o.is_a? Array or (o.is_a? Hash and expected == BasicTypes::KeyValue))
|
||||
case o
|
||||
when Array, BasicTypes::KeyValue
|
||||
if o.is_a? BasicTypes::KeyValue and expected != BasicTypes::KeyValue
|
||||
fail "expected #{expected.wsdl_name}, got KeyValue"
|
||||
fail "expected #{expected.wsdl_name} for '#{name}', got KeyValue"
|
||||
elsif expected == BasicTypes::KeyValue and not is_array
|
||||
xml.tag! name, attrs do
|
||||
xml.tag! 'key', o[0].to_s
|
||||
xml.tag! 'value', o[1].to_s
|
||||
end
|
||||
else
|
||||
fail "expected #{expected.wsdl_name}, got array" unless is_array
|
||||
fail "expected #{expected.wsdl_name} for '#{name}', got array" unless is_array
|
||||
o.each do |e|
|
||||
obj2xml xml, name, expected.wsdl_name, false, e, attrs
|
||||
end
|
||||
end
|
||||
when BasicTypes::ManagedObject
|
||||
fail "expected #{expected.wsdl_name}, got #{o.class.wsdl_name} for field #{name.inspect}" if expected and not expected >= o.class and not expected == BasicTypes::AnyType
|
||||
fail "expected #{expected.wsdl_name} for '#{name}', got #{o.class.wsdl_name} for field #{name.inspect}" if expected and not expected >= o.class and not expected == BasicTypes::AnyType
|
||||
xml.tag! name, o._ref, :type => o.class.wsdl_name
|
||||
when BasicTypes::DataObject
|
||||
fail "expected #{expected.wsdl_name}, got #{o.class.wsdl_name} for field #{name.inspect}" if expected and not expected >= o.class and not expected == BasicTypes::AnyType
|
||||
if expected and not expected >= o.class and not expected == BasicTypes::AnyType
|
||||
fail "expected #{expected.wsdl_name} for '#{name}', got #{o.class.wsdl_name} for field #{name.inspect}"
|
||||
end
|
||||
xml.tag! name, attrs.merge("xsi:type" => o.class.wsdl_name) do
|
||||
o.class.full_props_desc.each do |desc|
|
||||
if o.props.member? desc['name'].to_sym
|
||||
@ -151,11 +153,11 @@ class Connection < TrivialSoap
|
||||
if expected == BasicTypes::KeyValue and is_array
|
||||
obj2xml xml, name, type, is_array, o.to_a, attrs
|
||||
else
|
||||
fail "expected #{expected.wsdl_name}, got a hash" unless expected <= BasicTypes::DataObject
|
||||
fail "expected #{expected.wsdl_name} for '#{name}', got a hash" unless expected <= BasicTypes::DataObject
|
||||
obj2xml xml, name, type, false, expected.new(o), attrs
|
||||
end
|
||||
when true, false
|
||||
fail "expected #{expected.wsdl_name}, got a boolean" unless [BasicTypes::Boolean, BasicTypes::AnyType].member? expected
|
||||
fail "expected #{expected.wsdl_name} for '#{name}', got a boolean" unless [BasicTypes::Boolean, BasicTypes::AnyType].member? expected
|
||||
attrs['xsi:type'] = 'xsd:boolean' if expected == BasicTypes::AnyType
|
||||
xml.tag! name, (o ? '1' : '0'), attrs
|
||||
when Symbol, String
|
||||
@ -181,7 +183,7 @@ class Connection < TrivialSoap
|
||||
when BasicTypes::Int
|
||||
attrs['xsi:type'] = 'xsd:int'
|
||||
xml.tag! name, o.to_s, attrs
|
||||
else fail "unexpected object class #{o.class}"
|
||||
else fail "unexpected object class #{o.class} for '#{name}'"
|
||||
end
|
||||
xml
|
||||
rescue
|
||||
|
@ -43,6 +43,13 @@ class NewDeserializer
|
||||
|
||||
def deserialize node, type=nil
|
||||
type_attr = node['type']
|
||||
|
||||
# Work around for 1.5.x which doesn't populate node['type']
|
||||
# XXX what changed
|
||||
if node.attributes['type'] and not type_attr
|
||||
type_attr = node.attributes['type'].value
|
||||
end
|
||||
|
||||
type = type_attr if type_attr
|
||||
|
||||
if action = BUILTIN_TYPE_ACTIONS[type]
|
||||
@ -64,15 +71,18 @@ class NewDeserializer
|
||||
else fail
|
||||
end
|
||||
else
|
||||
if type =~ /:/
|
||||
type = type.split(":", 2)[1]
|
||||
end
|
||||
if type =~ /^ArrayOf/
|
||||
type = DEMANGLED_ARRAY_TYPES[$'] || $'
|
||||
return node.children.select(&:element?).map { |c| deserialize c, type }
|
||||
end
|
||||
|
||||
if type =~ /:/
|
||||
type = type.split(":", 2)[1]
|
||||
end
|
||||
klass = @loader.get(type) or fail "no such type #{type}"
|
||||
|
||||
klass = @loader.get(type) or fail "no such type '#{type}'"
|
||||
case klass.kind
|
||||
when :data
|
||||
traverse_data node, klass
|
||||
@ -229,7 +239,7 @@ class OldDeserializer
|
||||
end
|
||||
end
|
||||
|
||||
if ENV['RBVMOMI_NEW_DESERIALIZER'] == '1'
|
||||
if ENV['RBVMOMI_NEW_DESERIALIZER'] == '1' || true # Always use new one now
|
||||
Deserializer = NewDeserializer
|
||||
else
|
||||
Deserializer = OldDeserializer
|
||||
|
@ -49,9 +49,9 @@ class PBM < Connection
|
||||
@serviceInstance ||= VIM::PbmServiceInstance self, 'ServiceInstance'
|
||||
end
|
||||
|
||||
# Alias to serviceInstance.RetrieveServiceContent
|
||||
# Alias to serviceInstance.PbmRetrieveServiceContent
|
||||
def serviceContent
|
||||
@serviceContent ||= serviceInstance.RetrieveServiceContent
|
||||
@serviceContent ||= serviceInstance.PbmRetrieveServiceContent
|
||||
end
|
||||
|
||||
# @private
|
||||
|
61
share/vendor/ruby/gems/rbvmomi/lib/rbvmomi/sms.rb
vendored
Normal file
61
share/vendor/ruby/gems/rbvmomi/lib/rbvmomi/sms.rb
vendored
Normal file
@ -0,0 +1,61 @@
|
||||
# Copyright (c) 2013 VMware, Inc. All Rights Reserved.
|
||||
require 'rbvmomi'
|
||||
module RbVmomi
|
||||
|
||||
# A connection to one vSphere SMS endpoint.
|
||||
# @see #serviceInstance
|
||||
class SMS < Connection
|
||||
# Connect to a vSphere SMS endpoint
|
||||
#
|
||||
# @param [VIM] Connection to main vSphere API endpoint
|
||||
# @param [Hash] opts The options hash.
|
||||
# @option opts [String] :host Host to connect to.
|
||||
# @option opts [Numeric] :port (443) Port to connect to.
|
||||
# @option opts [Boolean] :ssl (true) Whether to use SSL.
|
||||
# @option opts [Boolean] :insecure (false) If true, ignore SSL certificate errors.
|
||||
# @option opts [String] :path (/sms/sdk) SDK endpoint path.
|
||||
# @option opts [Boolean] :debug (false) If true, print SOAP traffic to stderr.
|
||||
def self.connect vim, opts = {}
|
||||
fail unless opts.is_a? Hash
|
||||
opts[:host] = vim.host
|
||||
opts[:ssl] = true unless opts.member? :ssl or opts[:"no-ssl"]
|
||||
opts[:insecure] ||= true
|
||||
opts[:port] ||= (opts[:ssl] ? 443 : 80)
|
||||
opts[:path] ||= '/sms/sdk'
|
||||
opts[:ns] ||= 'urn:sms'
|
||||
rev_given = opts[:rev] != nil
|
||||
opts[:rev] = '4.0' unless rev_given
|
||||
opts[:debug] = (!ENV['RBVMOMI_DEBUG'].empty? rescue false) unless opts.member? :debug
|
||||
|
||||
new(opts).tap do |sms|
|
||||
sms.vcSessionCookie = vim.cookie.split('"')[1]
|
||||
end
|
||||
end
|
||||
|
||||
def vcSessionCookie= cookie
|
||||
@vcSessionCookie = cookie
|
||||
end
|
||||
|
||||
def rev= x
|
||||
super
|
||||
@serviceContent = nil
|
||||
end
|
||||
|
||||
# Return the ServiceInstance
|
||||
#
|
||||
# The ServiceInstance is the root of the vSphere inventory.
|
||||
def serviceInstance
|
||||
@serviceInstance ||= VIM::SmsServiceInstance self, 'ServiceInstance'
|
||||
end
|
||||
|
||||
# @private
|
||||
def pretty_print pp
|
||||
pp.text "SMS(#{@opts[:host]})"
|
||||
end
|
||||
|
||||
add_extension_dir File.join(File.dirname(__FILE__), "sms")
|
||||
load_vmodl(ENV['VMODL'] || File.join(File.dirname(__FILE__), "../../vmodl.db"))
|
||||
end
|
||||
|
||||
end
|
||||
|
7
share/vendor/ruby/gems/rbvmomi/lib/rbvmomi/sms/SmsStorageManager.rb
vendored
Normal file
7
share/vendor/ruby/gems/rbvmomi/lib/rbvmomi/sms/SmsStorageManager.rb
vendored
Normal file
@ -0,0 +1,7 @@
|
||||
class RbVmomi::SMS::SmsStorageManager
|
||||
|
||||
def RegisterProvider_Task2 providerSpec
|
||||
self.RegisterProvider_Task providerSpec
|
||||
end
|
||||
|
||||
end
|
@ -14,7 +14,7 @@ class RbVmomi::TrivialSoap
|
||||
@opts = opts
|
||||
return unless @opts[:host] # for testcases
|
||||
@debug = @opts[:debug]
|
||||
@cookie = nil
|
||||
@cookie = @opts[:cookie]
|
||||
@lock = Mutex.new
|
||||
@http = nil
|
||||
restart_http
|
||||
@ -36,7 +36,6 @@ class RbVmomi::TrivialSoap
|
||||
puts ex.backtrace.join("\n")
|
||||
end
|
||||
@http = Net::HTTP.new(@opts[:host], @opts[:port], @opts[:proxyHost], @opts[:proxyPort])
|
||||
|
||||
if @opts[:ssl]
|
||||
require 'net/https'
|
||||
@http.use_ssl = true
|
||||
@ -45,10 +44,6 @@ class RbVmomi::TrivialSoap
|
||||
else
|
||||
@http.verify_mode = OpenSSL::SSL::VERIFY_PEER
|
||||
end
|
||||
|
||||
@http.ssl_version = :TLSv1
|
||||
|
||||
|
||||
@http.cert = OpenSSL::X509::Certificate.new(@opts[:cert]) if @opts[:cert]
|
||||
@http.key = OpenSSL::PKey::RSA.new(@opts[:key]) if @opts[:key]
|
||||
end
|
||||
|
@ -52,7 +52,7 @@ class TypeLoader
|
||||
end
|
||||
|
||||
def get name
|
||||
fail unless name.is_a? String
|
||||
fail "name '#{name}' is #{name.class} expecting String" unless name.is_a? String
|
||||
|
||||
first_char = name[0].chr
|
||||
if first_char.downcase == first_char
|
||||
|
@ -41,6 +41,8 @@
|
||||
# computer (cluster), resource pool, vm_folder and datastore. Currently once
|
||||
# computed, a new updated placement can't be generated.
|
||||
class AdmissionControlledResourceScheduler
|
||||
attr_reader :rp
|
||||
|
||||
def initialize vim, opts = {}
|
||||
@vim = vim
|
||||
|
||||
@ -330,6 +332,10 @@ class AdmissionControlledResourceScheduler
|
||||
# datastore without much intelligence, as long as it passes admission control.
|
||||
# @return [VIM::Datastore] Chosen datastore
|
||||
def datastore placementHint = nil
|
||||
if @datastore
|
||||
return @datastore
|
||||
end
|
||||
|
||||
pod_datastores = pick_computer.datastore & datastores
|
||||
|
||||
eligible = pod_datastores.select do |ds|
|
||||
|
@ -102,6 +102,13 @@ class CachedOvfDeployer
|
||||
# simplicity this function assumes we need to read the OVF file
|
||||
# ourselves to know the names, and we map all of them to the same
|
||||
# VIM::Network.
|
||||
|
||||
# If we're handling a file:// URI we need to strip the scheme as open-uri
|
||||
# can't handle them.
|
||||
if URI(ovf_url).scheme == "file" && URI(ovf_url).host.nil?
|
||||
ovf_url = URI(ovf_url).path
|
||||
end
|
||||
|
||||
ovf = open(ovf_url, 'r'){|io| Nokogiri::XML(io.read)}
|
||||
ovf.remove_namespaces!
|
||||
networks = ovf.xpath('//NetworkSection/Network').map{|x| x['name']}
|
||||
@ -178,11 +185,10 @@ class CachedOvfDeployer
|
||||
# prepare it for (linked) cloning and mark it as a template to signal
|
||||
# we are done.
|
||||
if !wait_for_template
|
||||
vm.add_delta_disk_layer_on_all_disks
|
||||
if opts[:config]
|
||||
# XXX: Should we add a version that does retries?
|
||||
vm.ReconfigVM_Task(:spec => opts[:config]).wait_for_completion
|
||||
end
|
||||
config = opts[:config] || {}
|
||||
config = vm.update_spec_add_delta_disk_layer_on_all_disks(config)
|
||||
# XXX: Should we add a version that does retries?
|
||||
vm.ReconfigVM_Task(:spec => config).wait_for_completion
|
||||
vm.MarkAsTemplate
|
||||
end
|
||||
end
|
||||
@ -207,7 +213,7 @@ class CachedOvfDeployer
|
||||
# or nil
|
||||
def lookup_template template_name
|
||||
template_path = "#{template_name}-#{@computer.name}"
|
||||
template = @template_folder.traverse(template_path, VIM::VirtualMachine)
|
||||
template = @template_folder.traverse(template_path, RbVmomi::VIM::VirtualMachine)
|
||||
if template
|
||||
config = template.config
|
||||
is_template = config && config.template
|
||||
|
@ -93,7 +93,8 @@ class PerfAggregator
|
||||
RbVmomi::VIM.SelectionSpec(:name => 'tsFolder'),
|
||||
RbVmomi::VIM.SelectionSpec(:name => 'tsDatacenterVmFolder'),
|
||||
RbVmomi::VIM.SelectionSpec(:name => 'tsDatacenterHostFolder'),
|
||||
RbVmomi::VIM.SelectionSpec(:name => 'tsCluster'),
|
||||
RbVmomi::VIM.SelectionSpec(:name => 'tsClusterRP'),
|
||||
RbVmomi::VIM.SelectionSpec(:name => 'tsClusterHost'),
|
||||
]
|
||||
),
|
||||
RbVmomi::VIM.TraversalSpec(
|
||||
@ -115,7 +116,7 @@ class PerfAggregator
|
||||
]
|
||||
),
|
||||
RbVmomi::VIM.TraversalSpec(
|
||||
:name => 'tsCluster',
|
||||
:name => 'tsClusterRP',
|
||||
:type => 'ClusterComputeResource',
|
||||
:path => 'resourcePool',
|
||||
:skip => false,
|
||||
@ -123,6 +124,13 @@ class PerfAggregator
|
||||
RbVmomi::VIM.SelectionSpec(:name => 'tsRP'),
|
||||
]
|
||||
),
|
||||
RbVmomi::VIM.TraversalSpec(
|
||||
:name => 'tsClusterHost',
|
||||
:type => 'ClusterComputeResource',
|
||||
:path => 'host',
|
||||
:skip => false,
|
||||
:selectSet => []
|
||||
),
|
||||
RbVmomi::VIM.TraversalSpec(
|
||||
:name => 'tsRP',
|
||||
:type => 'ResourcePool',
|
||||
@ -141,6 +149,7 @@ class PerfAggregator
|
||||
:pathSet => ['name', 'parent', 'summary.effectiveCpu', 'summary.effectiveMemory']
|
||||
},
|
||||
{ :type => 'ResourcePool', :pathSet => ['name', 'parent'] },
|
||||
{ :type => 'HostSystem', :pathSet => ['name', 'parent', 'runtime.connectionState'] },
|
||||
{ :type => 'VirtualMachine', :pathSet => vm_prop_names },
|
||||
]
|
||||
)
|
||||
@ -316,9 +325,18 @@ class PerfAggregator
|
||||
'virtualDisk.totalWriteLatency' => :avg_ignore_zero,
|
||||
}
|
||||
end
|
||||
host_perf_metrics = opts[:host_perf_metrics]
|
||||
if !host_perf_metrics
|
||||
host_perf_metrics = {
|
||||
'cpu.usage' => :avg,
|
||||
'mem.usage' => :avg,
|
||||
}
|
||||
end
|
||||
|
||||
vms_props, inventory = all_inventory_flat root_folder, prop_names
|
||||
vms = vms_props.keys
|
||||
|
||||
hosts_props = inventory.select{|k, v| k.is_a?(VIM::HostSystem)}
|
||||
|
||||
conn = root_folder._connection
|
||||
sc = conn.serviceContent
|
||||
@ -349,8 +367,31 @@ class PerfAggregator
|
||||
end
|
||||
raise
|
||||
end
|
||||
|
||||
connected_hosts = hosts_props.select do |k,v|
|
||||
v['runtime.connectionState'] != "disconnected"
|
||||
end
|
||||
if connected_hosts.length > 0
|
||||
hosts_stats = pm.retrieve_stats(
|
||||
connected_hosts.keys, host_perf_metrics.keys,
|
||||
:max_samples => 3
|
||||
)
|
||||
end
|
||||
hosts_props.each do |host, props|
|
||||
if !connected_hosts[host]
|
||||
next
|
||||
end
|
||||
|
||||
stats = hosts_stats[host] || {}
|
||||
stats = stats[:metrics] || {}
|
||||
stats = _aggregate_metrics [stats], host_perf_metrics
|
||||
props.merge!(stats)
|
||||
end
|
||||
|
||||
vms_props.each do |vm, props|
|
||||
if !connected_vms.member?(vm)
|
||||
next
|
||||
end
|
||||
props['num.vm'] = 1
|
||||
powered_on = (props['runtime.powerState'] == 'poweredOn')
|
||||
props['num.poweredonvm'] = powered_on ? 1 : 0
|
||||
@ -392,25 +433,35 @@ class PerfAggregator
|
||||
props['vc_uuid'] = vc_uuid
|
||||
end
|
||||
|
||||
[vms_props, inventory]
|
||||
[vms_props, inventory, hosts_props]
|
||||
end
|
||||
|
||||
def collect_info_on_all_vms root_folders, opts = {}
|
||||
log "Fetching information from all VCs ..."
|
||||
vms_props = {}
|
||||
hosts_props = {}
|
||||
inventory = {}
|
||||
lock = Mutex.new
|
||||
root_folders.map do |root_folder|
|
||||
Thread.new do
|
||||
single_vms_props, single_inventory =
|
||||
_collect_info_on_all_vms_single(root_folder, opts)
|
||||
|
||||
lock.synchronize do
|
||||
vms_props.merge!(single_vms_props)
|
||||
if inventory['root']
|
||||
single_inventory['root']['children'] += inventory['root']['children']
|
||||
begin
|
||||
single_vms_props, single_inventory, single_hosts_props =
|
||||
_collect_info_on_all_vms_single(root_folder, opts)
|
||||
|
||||
lock.synchronize do
|
||||
vms_props.merge!(single_vms_props)
|
||||
if inventory['root']
|
||||
single_inventory['root']['children'] += inventory['root']['children']
|
||||
end
|
||||
inventory.merge!(single_inventory)
|
||||
hosts_props.merge!(single_hosts_props)
|
||||
end
|
||||
inventory.merge!(single_inventory)
|
||||
rescue Exception => ex
|
||||
log "#{ex.class}: #{ex.message}"
|
||||
ex.backtrace.each do |line|
|
||||
log line
|
||||
end
|
||||
raise
|
||||
end
|
||||
end
|
||||
end.each{|t| t.join}
|
||||
@ -418,6 +469,7 @@ class PerfAggregator
|
||||
log "Make data marshal friendly ..."
|
||||
inventory = _make_marshal_friendly(inventory)
|
||||
vms_props = _make_marshal_friendly(vms_props)
|
||||
hosts_props = _make_marshal_friendly(hosts_props)
|
||||
|
||||
log "Perform external post processing ..."
|
||||
if @vm_processing_callback
|
||||
@ -442,7 +494,11 @@ class PerfAggregator
|
||||
@inventory = inventory
|
||||
@vms_props = vms_props
|
||||
|
||||
nil
|
||||
{
|
||||
'inventory' => inventory,
|
||||
'vms_props' => vms_props,
|
||||
'hosts_props' => hosts_props,
|
||||
}
|
||||
end
|
||||
|
||||
def _make_marshal_friendly hash
|
||||
|
@ -13,6 +13,7 @@ class VIM < Connection
|
||||
# @option opts [Numeric] :port (443) Port to connect to.
|
||||
# @option opts [Boolean] :ssl (true) Whether to use SSL.
|
||||
# @option opts [Boolean] :insecure (false) If true, ignore SSL certificate errors.
|
||||
# @option opts [String] :cookie If set, use cookie to connect instead of user/password
|
||||
# @option opts [String] :user (root) Username.
|
||||
# @option opts [String] :password Password.
|
||||
# @option opts [String] :path (/sdk) SDK endpoint path.
|
||||
@ -20,6 +21,7 @@ class VIM < Connection
|
||||
def self.connect opts
|
||||
fail unless opts.is_a? Hash
|
||||
fail "host option required" unless opts[:host]
|
||||
opts[:cookie] ||= nil
|
||||
opts[:user] ||= 'root'
|
||||
opts[:password] ||= ''
|
||||
opts[:ssl] = true unless opts.member? :ssl or opts[:"no-ssl"]
|
||||
@ -32,10 +34,12 @@ class VIM < Connection
|
||||
opts[:debug] = (!ENV['RBVMOMI_DEBUG'].empty? rescue false) unless opts.member? :debug
|
||||
|
||||
new(opts).tap do |vim|
|
||||
vim.serviceContent.sessionManager.Login :userName => opts[:user], :password => opts[:password]
|
||||
unless opts[:cookie]
|
||||
vim.serviceContent.sessionManager.Login :userName => opts[:user], :password => opts[:password]
|
||||
end
|
||||
unless rev_given
|
||||
rev = vim.serviceContent.about.apiVersion
|
||||
vim.rev = [rev, '5.0'].min
|
||||
vim.rev = [rev, '5.5'].min
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -45,7 +49,7 @@ class VIM < Connection
|
||||
self.cookie = nil
|
||||
super
|
||||
end
|
||||
|
||||
|
||||
def rev= x
|
||||
super
|
||||
@serviceContent = nil
|
||||
@ -85,11 +89,36 @@ class VIM < Connection
|
||||
def pretty_print pp
|
||||
pp.text "VIM(#{@opts[:host]})"
|
||||
end
|
||||
|
||||
|
||||
def instanceUuid
|
||||
serviceContent.about.instanceUuid
|
||||
end
|
||||
|
||||
def get_log_lines logKey, lines=5, start=nil, host=nil
|
||||
diagMgr = self.serviceContent.diagnosticManager
|
||||
if !start
|
||||
log = diagMgr.BrowseDiagnosticLog(:host => host, :key => logKey, :start => 999999999)
|
||||
lineEnd = log.lineEnd
|
||||
start = lineEnd - lines
|
||||
end
|
||||
start = start < 0 ? 0 : start
|
||||
log = diagMgr.BrowseDiagnosticLog(:host => host, :key => logKey, :start => start)
|
||||
if log.lineText.size > 0
|
||||
[log.lineText.slice(-lines, log.lineText.size), log.lineEnd]
|
||||
else
|
||||
[log.lineText, log.lineEnd]
|
||||
end
|
||||
end
|
||||
|
||||
def get_log_keys host=nil
|
||||
diagMgr = self.serviceContent.diagnosticManager
|
||||
keys = []
|
||||
diagMgr.QueryDescriptions(:host => host).each do |desc|
|
||||
keys << "#{desc.key}"
|
||||
end
|
||||
keys
|
||||
end
|
||||
|
||||
add_extension_dir File.join(File.dirname(__FILE__), "vim")
|
||||
(ENV['RBVMOMI_VIM_EXTENSION_PATH']||'').split(':').each { |dir| add_extension_dir dir }
|
||||
|
||||
|
@ -14,3 +14,4 @@ class RbVmomi::VIM::Datacenter
|
||||
vmFolder.traverse path, RbVmomi::VIM::VirtualMachine
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -35,61 +35,6 @@ class RbVmomi::VIM::Datastore
|
||||
fail "download failed" unless $?.success?
|
||||
end
|
||||
|
||||
# Download a file from this datastore.
|
||||
# @param remote_path [String] Source path on the datastore.
|
||||
# @param local_path [String] Destination path on the local machine.
|
||||
# @return [void]
|
||||
def download_to_stdout remote_path
|
||||
url = "http#{_connection.http.use_ssl? ? 's' : ''}://#{_connection.http.address}:#{_connection.http.port}#{mkuripath(remote_path)}"
|
||||
|
||||
pid = spawn CURLBIN, "-k", '--noproxy', '*', '-f',
|
||||
"-b", _connection.cookie,
|
||||
url
|
||||
|
||||
|
||||
Process.waitpid(pid, 0)
|
||||
fail "download failed" unless $?.success?
|
||||
end
|
||||
|
||||
def is_descriptor? remote_path
|
||||
url = "http#{_connection.http.use_ssl? ? 's' : ''}://#{_connection.http.address}:#{_connection.http.port}#{mkuripath(remote_path)}"
|
||||
|
||||
rout, wout = IO.pipe
|
||||
|
||||
pid = spawn CURLBIN, "-I", "-k", '--noproxy', '*', '-f',
|
||||
"-b", _connection.cookie,
|
||||
url,
|
||||
:out => wout,
|
||||
:err => '/dev/null'
|
||||
|
||||
Process.waitpid(pid, 0)
|
||||
fail "read image header failed" unless $?.success?
|
||||
|
||||
wout.close
|
||||
size = rout.readlines.select{|l| l.start_with?("Content-Length")}[0].sub("Content-Length: ","")
|
||||
rout.close
|
||||
size.chomp.to_i < 4096 # If <4k, then is a descriptor
|
||||
end
|
||||
|
||||
def get_text_file remote_path
|
||||
url = "http#{_connection.http.use_ssl? ? 's' : ''}://#{_connection.http.address}:#{_connection.http.port}#{mkuripath(remote_path)}"
|
||||
|
||||
rout, wout = IO.pipe
|
||||
pid = spawn CURLBIN, "-k", '--noproxy', '*', '-f',
|
||||
"-b", _connection.cookie,
|
||||
url,
|
||||
:out => wout,
|
||||
:err => '/dev/null'
|
||||
|
||||
Process.waitpid(pid, 0)
|
||||
fail "get text file failed" unless $?.success?
|
||||
|
||||
wout.close
|
||||
output = rout.readlines
|
||||
rout.close
|
||||
return output
|
||||
end
|
||||
|
||||
# Upload a file to this datastore.
|
||||
# @param remote_path [String] Destination path on the datastore.
|
||||
# @param local_path [String] Source path on the local machine.
|
||||
|
@ -53,6 +53,16 @@ class RbVmomi::VIM::Folder
|
||||
x if x.is_a? type
|
||||
end
|
||||
|
||||
# Retrieve a managed entity by inventory path.
|
||||
# @param path [String] A path of the form "My Folder/My Datacenter/vm/Discovered VM/VM1"
|
||||
# @return [VIM::ManagedEntity]
|
||||
def findByInventoryPath path
|
||||
propSpecs = {
|
||||
:entity => self, :inventoryPath => path
|
||||
}
|
||||
x = _connection.searchIndex.FindByInventoryPath(propSpecs)
|
||||
end
|
||||
|
||||
# Alias to <tt>traverse path, type, true</tt>
|
||||
# @see #traverse
|
||||
def traverse! path, type=Object
|
||||
|
@ -35,7 +35,12 @@ class RbVmomi::VIM::ManagedObject
|
||||
:type => self.class.wsdl_name
|
||||
}]
|
||||
}
|
||||
_connection.propertyCollector.RetrieveProperties(:specSet => [spec])[0].to_hash
|
||||
ret = _connection.propertyCollector.RetrieveProperties(:specSet => [spec])
|
||||
if ret && ret.length > 0
|
||||
ret[0].to_hash
|
||||
else
|
||||
{}
|
||||
end
|
||||
end
|
||||
|
||||
# Efficiently retrieve multiple properties from an object.
|
||||
|
@ -48,7 +48,16 @@ class RbVmomi::VIM::OvfManager
|
||||
result.warning.each{|x| puts "OVF Warning: #{x.localizedMessage.chomp}" }
|
||||
end
|
||||
|
||||
nfcLease = opts[:resourcePool].ImportVApp(:spec => result.importSpec,
|
||||
importSpec = result.importSpec
|
||||
if importSpec && importSpec.instantiationOst && importSpec.instantiationOst.child
|
||||
importSpec.instantiationOst.child.each do |child|
|
||||
child.section.map do |section|
|
||||
section.xml = _handle_ost(section.xml, opts)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
nfcLease = opts[:resourcePool].ImportVApp(:spec => importSpec,
|
||||
:folder => opts[:vmFolder],
|
||||
:host => opts[:host])
|
||||
|
||||
@ -56,30 +65,70 @@ class RbVmomi::VIM::OvfManager
|
||||
raise nfcLease.error if nfcLease.state == "error"
|
||||
begin
|
||||
nfcLease.HttpNfcLeaseProgress(:percent => 5)
|
||||
timeout, = nfcLease.collect 'info.leaseTimeout'
|
||||
puts "DEBUG: Timeout: #{timeout}"
|
||||
if timeout < 4 * 60
|
||||
puts "WARNING: OVF upload NFC lease timeout less than 4 minutes"
|
||||
end
|
||||
progress = 5.0
|
||||
result.fileItem.each do |fileItem|
|
||||
deviceUrl = nfcLease.info.deviceUrl.find{|x| x.importKey == fileItem.deviceId}
|
||||
leaseInfo, leaseState, leaseError = nfcLease.collect 'info', 'state', 'error'
|
||||
# Retry nfcLease.collect because of PR 969599:
|
||||
# If retrying property collector works, this means there is a network
|
||||
# or VC overloading problem.
|
||||
retrynum = 5
|
||||
i = 1
|
||||
while i <= retrynum && !leaseState
|
||||
puts "Retrying at iteration #{i}"
|
||||
sleep 1
|
||||
leaseInfo, leaseState, leaseError = nfcLease.collect 'info', 'state', 'error'
|
||||
i += 1
|
||||
end
|
||||
if leaseState != "ready"
|
||||
raise "NFC lease is no longer ready: #{leaseState}: #{leaseError}"
|
||||
end
|
||||
if leaseInfo == nil
|
||||
raise "NFC lease disappeared?"
|
||||
end
|
||||
deviceUrl = leaseInfo.deviceUrl.find{|x| x.importKey == fileItem.deviceId}
|
||||
if !deviceUrl
|
||||
raise "Couldn't find deviceURL for device '#{fileItem.deviceId}'"
|
||||
end
|
||||
|
||||
# XXX handle file:// URIs
|
||||
ovfFilename = opts[:uri].to_s
|
||||
tmp = ovfFilename.split(/\//)
|
||||
tmp.pop
|
||||
tmp << fileItem.path
|
||||
filename = tmp.join("/")
|
||||
|
||||
# If filename doesn't have a URI scheme, we're considering it a local file
|
||||
if URI(filename).scheme.nil?
|
||||
filename = "file://" + filename
|
||||
end
|
||||
|
||||
method = fileItem.create ? "PUT" : "POST"
|
||||
|
||||
keepAliveThread = Thread.new do
|
||||
while true
|
||||
sleep 2 * 60
|
||||
nfcLease.HttpNfcLeaseProgress(:percent => progress.to_i)
|
||||
sleep 1 * 60
|
||||
end
|
||||
end
|
||||
|
||||
href = deviceUrl.url.gsub("*", opts[:host].config.network.vnic[0].spec.ip.ipAddress)
|
||||
i = 1
|
||||
ip = nil
|
||||
begin
|
||||
begin
|
||||
puts "Iteration #{i}: Trying to get host's IP address ..."
|
||||
ip = opts[:host].config.network.vnic[0].spec.ip.ipAddress
|
||||
rescue Exception=>e
|
||||
puts "Iteration #{i}: Couldn't get host's IP address: #{e}"
|
||||
end
|
||||
sleep 1
|
||||
i += 1
|
||||
end while i <= 5 && !ip
|
||||
raise "Couldn't get host's IP address" unless ip
|
||||
href = deviceUrl.url.gsub("*", ip)
|
||||
downloadCmd = "#{CURLBIN} -L '#{URI::escape(filename)}'"
|
||||
uploadCmd = "#{CURLBIN} -Ss -X #{method} --insecure -T - -H 'Content-Type: application/x-vnd.vmware-streamVmdk' '#{URI::escape(href)}'"
|
||||
# Previously we used to append "-H 'Content-Length: #{fileItem.size}'"
|
||||
@ -96,12 +145,56 @@ class RbVmomi::VIM::OvfManager
|
||||
end
|
||||
|
||||
nfcLease.HttpNfcLeaseProgress(:percent => 100)
|
||||
vm = nfcLease.info.entity
|
||||
nfcLease.HttpNfcLeaseComplete
|
||||
raise nfcLease.error if nfcLease.state == "error"
|
||||
i = 1
|
||||
vm = nil
|
||||
begin
|
||||
begin
|
||||
puts "Iteration #{i}: Trying to access nfcLease.info.entity ..."
|
||||
vm = nfcLease.info.entity
|
||||
rescue Exception=>e
|
||||
puts "Iteration #{i}: Couldn't access nfcLease.info.entity: #{e}"
|
||||
end
|
||||
sleep 1
|
||||
i += 1
|
||||
end while i <= 5 && !vm
|
||||
raise "Couldn't access nfcLease.info.entity" unless vm
|
||||
|
||||
# Ignore sporadic connection errors caused by PR 1019166..
|
||||
# Three attempts are made to execute HttpNfcLeaseComplete.
|
||||
# Not critical if none goes through, as long as vm is obtained
|
||||
#
|
||||
# TODO: find the reason why HttpNfcLeaseComplete gets a wrong
|
||||
# response (RetrievePropertiesResponse)
|
||||
i = 0
|
||||
begin
|
||||
nfcLease.HttpNfcLeaseComplete
|
||||
puts "HttpNfcLeaseComplete succeeded"
|
||||
rescue RbVmomi::VIM::InvalidState
|
||||
puts "HttpNfcLeaseComplete already finished.."
|
||||
rescue Exception => e
|
||||
puts "HttpNfcLeaseComplete failed at iteration #{i} with exception: #{e}"
|
||||
i += 1
|
||||
retry if i < 3
|
||||
puts "Giving up HttpNfcLeaseComplete.."
|
||||
end
|
||||
vm
|
||||
end
|
||||
rescue Exception
|
||||
(nfcLease.HttpNfcLeaseAbort rescue nil) if nfcLease
|
||||
raise
|
||||
end
|
||||
|
||||
def _handle_ost ost, opts = {}
|
||||
ost = Nokogiri::XML(ost)
|
||||
if opts[:vservice] == ['com.vmware.vim.vsm:extension_vservice']
|
||||
ost.xpath('//vmw:Annotations/vmw:Providers/vmw:Provider').each do |x|
|
||||
x['vmw:selected'] = 'selected'
|
||||
end
|
||||
ost.xpath('//vmw:Annotations/vmw:Providers').each do |x|
|
||||
x['vmw:selected'] = 'com.vmware.vim.vsm:extension_vservice'
|
||||
end
|
||||
end
|
||||
ost.to_s
|
||||
end
|
||||
end
|
||||
|
@ -46,13 +46,21 @@ class RbVmomi::VIM::PerformanceManager
|
||||
end
|
||||
end
|
||||
|
||||
metric_ids = metrics.map do |x|
|
||||
instances = opts[:instance] || '*'
|
||||
if !instances.is_a?(Array)
|
||||
instances = [instances]
|
||||
end
|
||||
metric_ids = []
|
||||
metrics.each do |x|
|
||||
counter = perfcounter_hash[x]
|
||||
if !counter
|
||||
pp perfcounter_hash.keys
|
||||
fail "Counter for #{x} couldn't be found"
|
||||
end
|
||||
RbVmomi::VIM::PerfMetricId(:counterId => counter.key, :instance => '*')
|
||||
instances.each do |instance|
|
||||
metric_ids << RbVmomi::VIM::PerfMetricId(:counterId => counter.key,
|
||||
:instance => instance)
|
||||
end
|
||||
end
|
||||
query_specs = objects.map do |obj|
|
||||
RbVmomi::VIM::PerfQuerySpec({
|
||||
@ -65,19 +73,36 @@ class RbVmomi::VIM::PerformanceManager
|
||||
end
|
||||
stats = QueryPerf(:querySpec => query_specs)
|
||||
|
||||
Hash[stats.map do |res|
|
||||
[
|
||||
res.entity,
|
||||
{
|
||||
:sampleInfo => res.sampleInfo,
|
||||
:metrics => Hash[res.value.map do |metric|
|
||||
[perfcounter_idhash[metric.id.counterId].name, metric.value]
|
||||
end]
|
||||
}
|
||||
]
|
||||
end]
|
||||
if !opts[:multi_instance]
|
||||
Hash[stats.map do |res|
|
||||
[
|
||||
res.entity,
|
||||
{
|
||||
:sampleInfo => res.sampleInfo,
|
||||
:metrics => Hash[res.value.map do |metric|
|
||||
metric_name = perfcounter_idhash[metric.id.counterId].name
|
||||
[metric_name, metric.value]
|
||||
end]
|
||||
}
|
||||
]
|
||||
end]
|
||||
else
|
||||
Hash[stats.map do |res|
|
||||
[
|
||||
res.entity,
|
||||
{
|
||||
:sampleInfo => res.sampleInfo,
|
||||
:metrics => Hash[res.value.map do |metric|
|
||||
metric_name = perfcounter_idhash[metric.id.counterId].name
|
||||
[[metric_name, metric.id.instance], metric.value]
|
||||
end]
|
||||
}
|
||||
]
|
||||
end]
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
def active_intervals
|
||||
intervals = historicalInterval
|
||||
Hash[(1..4).map { |level| [level, intervals.select { |x| x.enabled && x.level >= level }] }]
|
||||
|
@ -34,26 +34,41 @@ class RbVmomi::VIM::VirtualMachine
|
||||
def add_delta_disk_layer_on_all_disks
|
||||
devices, = self.collect 'config.hardware.device'
|
||||
disks = devices.grep(RbVmomi::VIM::VirtualDisk)
|
||||
# XXX: Should create a single reconfig spec instead of one per disk
|
||||
spec = update_spec_add_delta_disk_layer_on_all_disks
|
||||
self.ReconfigVM_Task(:spec => spec).wait_for_completion
|
||||
end
|
||||
|
||||
# Updates a passed in spec to perform the task of adding a delta disk layer
|
||||
# on top of all disks. Does the same as add_delta_disk_layer_on_all_disks
|
||||
# but instead of issuing the ReconfigVM_Task, it just constructs the
|
||||
# spec, so that the caller can batch a couple of updates into one
|
||||
# ReconfigVM_Task.
|
||||
def update_spec_add_delta_disk_layer_on_all_disks spec = {}
|
||||
devices, = self.collect 'config.hardware.device'
|
||||
disks = devices.grep(RbVmomi::VIM::VirtualDisk)
|
||||
device_change = []
|
||||
disks.each do |disk|
|
||||
spec = {
|
||||
:deviceChange => [
|
||||
{
|
||||
:operation => :remove,
|
||||
:device => disk
|
||||
},
|
||||
{
|
||||
:operation => :add,
|
||||
:fileOperation => :create,
|
||||
:device => disk.dup.tap { |x|
|
||||
x.backing = x.backing.dup
|
||||
x.backing.fileName = "[#{disk.backing.datastore.name}]"
|
||||
x.backing.parent = disk.backing
|
||||
},
|
||||
}
|
||||
]
|
||||
device_change << {
|
||||
:operation => :remove,
|
||||
:device => disk
|
||||
}
|
||||
device_change << {
|
||||
:operation => :add,
|
||||
:fileOperation => :create,
|
||||
:device => disk.dup.tap { |x|
|
||||
x.backing = x.backing.dup
|
||||
x.backing.fileName = "[#{disk.backing.datastore.name}]"
|
||||
x.backing.parent = disk.backing
|
||||
},
|
||||
}
|
||||
self.ReconfigVM_Task(:spec => spec).wait_for_completion
|
||||
end
|
||||
if spec.is_a?(RbVmomi::VIM::VirtualMachineConfigSpec)
|
||||
spec.deviceChange ||= []
|
||||
spec.deviceChange += device_change
|
||||
else
|
||||
spec[:deviceChange] ||= []
|
||||
spec[:deviceChange] += device_change
|
||||
end
|
||||
spec
|
||||
end
|
||||
end
|
||||
|
BIN
share/vendor/ruby/gems/rbvmomi/vmodl.db
vendored
BIN
share/vendor/ruby/gems/rbvmomi/vmodl.db
vendored
Binary file not shown.
Loading…
x
Reference in New Issue
Block a user