mirror of
https://github.com/OpenNebula/one.git
synced 2025-01-11 05:17:41 +03:00
F #5207: vCenter disks can be resized when VM in poweroff
This commit is contained in:
parent
a5edba2a36
commit
00b7d8607a
@ -1031,6 +1031,7 @@ TM_VCENTER_FILES="src/tm_mad/vcenter/clone \
|
||||
src/tm_mad/vcenter/cpds \
|
||||
src/tm_mad/vcenter/premigrate \
|
||||
src/tm_mad/vcenter/postmigrate \
|
||||
src/tm_mad/vcenter/resize \
|
||||
src/tm_mad/vcenter/snap_create \
|
||||
src/tm_mad/vcenter/snap_create_live \
|
||||
src/tm_mad/vcenter/snap_delete \
|
||||
|
@ -1 +0,0 @@
|
||||
../common/not_supported.sh
|
89
src/tm_mad/vcenter/resize
Executable file
89
src/tm_mad/vcenter/resize
Executable file
@ -0,0 +1,89 @@
|
||||
#!/usr/bin/env ruby
|
||||
|
||||
# ---------------------------------------------------------------------------- #
|
||||
# Copyright 2002-2017, OpenNebula Project, OpenNebula Systems #
|
||||
# #
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may #
|
||||
# not use this file except in compliance with the License. You may obtain #
|
||||
# a copy of the License at #
|
||||
# #
|
||||
# http://www.apache.org/licenses/LICENSE-2.0 #
|
||||
# #
|
||||
# Unless required by applicable law or agreed to in writing, software #
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, #
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. #
|
||||
# See the License for the specific language governing permissions and #
|
||||
# limitations under the License. #
|
||||
# ---------------------------------------------------------------------------- #
|
||||
|
||||
# resize image size vmid
|
||||
|
||||
ONE_LOCATION = ENV["ONE_LOCATION"] if !defined?(ONE_LOCATION)
|
||||
|
||||
if !ONE_LOCATION
|
||||
RUBY_LIB_LOCATION = "/usr/lib/one/ruby" if !defined?(RUBY_LIB_LOCATION)
|
||||
else
|
||||
RUBY_LIB_LOCATION = ONE_LOCATION + "/lib/ruby" if !defined?(RUBY_LIB_LOCATION)
|
||||
end
|
||||
|
||||
$: << RUBY_LIB_LOCATION
|
||||
$: << File.dirname(__FILE__)
|
||||
|
||||
require 'vcenter_driver'
|
||||
|
||||
src = ARGV[0]
|
||||
new_size = ARGV[1]
|
||||
vmid = ARGV[2]
|
||||
|
||||
check_valid src,"src"
|
||||
check_valid new_size,"new_size"
|
||||
check_valid vmid,"vmid"
|
||||
|
||||
disk_id = src.split(".")[-1]
|
||||
hostname, = src.split ":"
|
||||
|
||||
# Get host ID
|
||||
host = VCenterDriver::VIHelper.find_by_name(OpenNebula::HostPool, hostname)
|
||||
host_id = host['ID']
|
||||
|
||||
# Get OpenNebula VM
|
||||
one_vm = VCenterDriver::VIHelper.one_item(OpenNebula::VirtualMachine, vmid)
|
||||
vm_ref = one_vm['DEPLOY_ID']
|
||||
|
||||
begin
|
||||
# This action is only possible when VM in ACTIVE / DISK_RESIZE_POWEROFF
|
||||
if one_vm['LCM_STATE'].to_i != 63
|
||||
raise "'disk-resize' operation is not supported for vCenter running VMs."
|
||||
end
|
||||
|
||||
vi_client = VCenterDriver::VIClient.new_from_host(host_id)
|
||||
|
||||
vm = VCenterDriver::VirtualMachine.new_from_ref(vm_ref, vi_client)
|
||||
|
||||
# Cannot resize if VM has snapshots
|
||||
if vm.has_snapshots?
|
||||
raise "'disk-resize' operation is not supported for VMs with system snapshots."
|
||||
end
|
||||
|
||||
# Get disk element to be resized
|
||||
disk = one_vm.retrieve_xmlelements("TEMPLATE/DISK[DISK_ID=#{disk_id}]").first
|
||||
|
||||
if disk["ORIGINAL_SIZE"].to_i >= new_size.to_i
|
||||
raise "'disk-resize' cannot decrease the disk's size"
|
||||
end
|
||||
|
||||
# Resize operation
|
||||
if !disk["OPENNEBULA_MANAGED"] || disk["OPENNEBULA_MANAGED"].downcase != "no" &&
|
||||
vm.resize_managed_disk(disk,new_size)
|
||||
else
|
||||
vm.resize_unmanaged_disk(disk, new_size)
|
||||
end
|
||||
|
||||
rescue Exception => e
|
||||
message = "Error resizing disk #{disk_id} for VM #{one_vm["NAME"]} "\
|
||||
"Reason: #{e.message}\n#{e.backtrace}"
|
||||
STDERR.puts error_message(message)
|
||||
exit -1
|
||||
ensure
|
||||
vi_client.close_connection if vi_client
|
||||
end
|
@ -2111,6 +2111,100 @@ class VirtualMachine < Template
|
||||
end
|
||||
end
|
||||
|
||||
def resize_unmanaged_disk(disk, new_size)
|
||||
|
||||
resize_hash = {}
|
||||
disks = []
|
||||
found = false
|
||||
|
||||
unmanaged_keys = get_unmanaged_keys
|
||||
vc_disks = get_vcenter_disks
|
||||
|
||||
vc_disks.each do |vcenter_disk|
|
||||
if unmanaged_keys.key?("opennebula.disk.#{disk["DISK_ID"]}")
|
||||
device_key = unmanaged_keys["opennebula.disk.#{disk["DISK_ID"]}"].to_i
|
||||
|
||||
if device_key == vcenter_disk[:key].to_i
|
||||
|
||||
if disk["SIZE"].to_i <= disk["ORIGINAL_SIZE"].to_i
|
||||
raise "Disk size cannot be shrinked."
|
||||
end
|
||||
|
||||
# Edit capacity setting new size in KB
|
||||
d = vcenter_disk[:device]
|
||||
d.capacityInKB = disk["SIZE"].to_i * 1024
|
||||
disks << { :device => d, :operation => :edit }
|
||||
|
||||
found = true
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
raise "Unmanaged disk could not be found to apply resize operation." if !found
|
||||
|
||||
if !disks.empty?
|
||||
resize_hash[:deviceChange] = disks
|
||||
@item.ReconfigVM_Task(:spec => resize_hash).wait_for_completion
|
||||
else
|
||||
raise "Device was not found after attaching it to VM in poweroff."
|
||||
end
|
||||
end
|
||||
|
||||
def resize_managed_disk(disk, new_size)
|
||||
|
||||
resize_hash = {}
|
||||
|
||||
unmanaged_keys = get_unmanaged_keys
|
||||
vc_disks = get_vcenter_disks
|
||||
|
||||
# Get vcenter device to be detached and remove if found
|
||||
device = disk_attached_to_vm(disk, unmanaged_keys, vc_disks)
|
||||
|
||||
# If the disk is being attached in poweroff, reconfigure the VM
|
||||
if !device
|
||||
spec_hash = {}
|
||||
device_change = []
|
||||
|
||||
# Get an array with disk paths in OpenNebula's vm template
|
||||
disks_in_onevm_vector = disks_in_onevm(unmanaged_keys, vc_disks)
|
||||
|
||||
device_change_ds, device_change_spod, device_change_spod_ids = device_attach_disks(disks_in_onevm_vector, vc_disks)
|
||||
device_change += device_change_ds
|
||||
|
||||
# Create volatile disks in StorageDRS if any
|
||||
if !device_change_spod.empty?
|
||||
spec_hash[:extraConfig] = create_storagedrs_disks(device_change_spod, device_change_spod_ids)
|
||||
end
|
||||
|
||||
# Common reconfigure task
|
||||
spec_hash[:deviceChange] = device_change
|
||||
spec = RbVmomi::VIM.VirtualMachineConfigSpec(spec_hash)
|
||||
@item.ReconfigVM_Task(:spec => spec).wait_for_completion
|
||||
|
||||
# Check again if device has now been attached
|
||||
unmanaged_keys = get_unmanaged_keys
|
||||
vc_disks = get_vcenter_disks
|
||||
device = disk_attached_to_vm(disk, unmanaged_keys, vc_disks)
|
||||
|
||||
if !device
|
||||
raise "Device was not found after attaching it to VM in poweroff."
|
||||
end
|
||||
end
|
||||
|
||||
# Resize disk now that we know that it's part of the VM
|
||||
if device
|
||||
vcenter_disk = device[:device]
|
||||
vcenter_disk.capacityInKB = new_size.to_i * 1024
|
||||
resize_hash[:deviceChange] = [{
|
||||
:operation => :edit,
|
||||
:device => vcenter_disk
|
||||
}]
|
||||
|
||||
@item.ReconfigVM_Task(:spec => resize_hash).wait_for_completion
|
||||
end
|
||||
end
|
||||
|
||||
def has_snapshots?
|
||||
self['rootSnapshot'] && !self['rootSnapshot'].empty?
|
||||
end
|
||||
|
Loading…
Reference in New Issue
Block a user