I am trying to reconfigure a VMWare VM, it has options for Memory and Processors; however, I don’t see anything for disks. Is there a way to resize a VMWare disk from the portal?
Hi,
You can do this, by creating a custom button with a custom method.
This feature is not built-in by default, for I mean.
Would you have an example or a document you can point me to? I am fairly new to the environment and still learning. Thanks.
Here’s what we’re using. We have a button attached to VMs that calls a Service Dialog to gather the disk information (size and disk). Currently we assume there’s only one SCSI controller, so there’s room for improvement, but this should do the heavy lifting.
###################################
#
# EVM Automate Method: expand_disk
#
# Notes: This method is used to increase the size of a VMWare VM disks.
#
# Inputs: $evm.root['vm'], dialog_size(GB)
#
###################################
begin
# Method for logging
def log(level, message)
@method = 'expand_disk'
$evm.log(level, "#{@method} - #{message}")
end
# dump_root
def dump_root()
log(:info, "Root:<$evm.root> Begin $evm.root.attributes")
$evm.root.attributes.sort.each { |k, v| log(:info, "Root:<$evm.root> Attribute - #{k}: #{v}")}
log(:info, "Root:<$evm.root> End $evm.root.attributes")
log(:info, "")
end
log(:info, "CFME Automate Method Started")
# dump all root attributes to the log
dump_root
def ensure_vm_available(vm_base, ems)
unavailable_reason = false
%w(ems vm_base).each do |nillable|
if eval(nillable).nil?
unavailable_reason = nillable
break
end
end
automate_retry(30, "#{unavailable_reason} is not available.") if unavailable_reason
end
def resizeDisk(vm, disk_number, new_disk_size_in_kb)
vm_base = vm.object_send('instance_eval', 'self')
ems = vm.ext_management_system
ensure_vm_available vm_base, ems
ems.object_send('instance_eval', '
def resize_disk(vm, diskIndex, new_disk_size_in_kb)
#self.get_vim_vm_by_mor(vm.ems_ref) do | vimVm |
vm.with_provider_object do | vimVm |
devices = vimVm.send(:getProp, "config.hardware")["config"]["hardware"]["device"]
matchedDev = nil
currentDiskIndex = 0
devices.each do | dev |
next if dev.xsiType != "VirtualDisk"
if diskIndex == currentDiskIndex
matchedDev = dev
break
end
currentDiskIndex += 1
end
raise "resize_disk: disk #{diskIndex} not found" unless matchedDev
$log.info("resize_disk: resizing using matched device at #{diskIndex}")
vmConfigSpec = VimHash.new("VirtualMachineConfigSpec") do |vmcs|
vmcs.deviceChange = VimArray.new("ArrayOfVirtualDeviceConfigSpec") do |vmcs_vca|
vmcs_vca << VimHash.new("VirtualDeviceConfigSpec") do |vdcs|
vdcs.operation = "edit".freeze
vdcs.device = VimHash.new("VirtualDisk") do |vDev|
vDev.key = matchedDev["key"]
vDev.controllerKey = matchedDev["controllerKey"]
vDev.unitNumber = matchedDev["unitNumber"]
vDev.backing = matchedDev["backing"]
vDev.capacityInKB = new_disk_size_in_kb
end
end
end
end
$log.info("resize_disk: attempting to reconfigure vm with spec: \'#{vmConfigSpec}\'")
vimVm.send(:reconfig, vmConfigSpec)
end
end')
ems.object_send('resize_disk', vm_base, disk_number, new_disk_size_in_kb)
end
def automate_retry(seconds, reason)
$evm.root['ae_result'] = 'retry'
$evm.root['ae_retry_interval'] = "#{seconds.to_i}.seconds"
$evm.root['ae_reason'] = reason
log(:info, "Retrying #{@method} after #{seconds} seconds, because '#{reason}'")
exit MIQ_OK
end
# Dump all root object attributes
automate_retry(30, "$evm.root not yet ready.") if $evm.root.nil?
# Get dialog_disk_number variable from root hash if nil convert to zero
DISK_NUMBER = $evm.root['dialog_diskindex'].to_i
log(:info,"DISK_NUMBER: '#{DISK_NUMBER}'")
vm = $evm.root['vm']
raise "VM object not found" if vm.nil?
# This method only works with VMware VMs currently
raise "Invalid vendor: #{vm.vendor}" unless vm.vendor.downcase == 'vmware'
sizeGB = $evm.root['dialog_disksize'].to_i
log(:info,"Detected VM:'#{vm.name}' vendor:'#{vm.vendor}' DISK_NUMBER:'#{DISK_NUMBER}' sizeGB:'#{sizeGB}'")
log(:info, "Expanding disk to #{sizeGB}GB")
new_disk_size_in_kb = (sizeGB * 1024**2)
begin
resizeDisk(vm, DISK_NUMBER, new_disk_size_in_kb)
rescue => e
if e.message =~ /VimFault/
log(:warn, "Encountered VimFault: #{e.inspect}")
automate_retry(30, "Encountered VimFault #{e.inspect}")
end
log(:error, "e: #{e}")
log(:error, "e.inspect: #{e.inspect}")
log(:error,"[#{e}]\n#{e.backtrace.join("\n")}")
log(:error, "e.message: #{e.message}")
end
log(:info,"EVM Automate Method Ended")
exit MIQ_OK
#
# Set Ruby rescue behavior
#
rescue => err
$evm.log("error","[#{err}]\n#{err.backtrace.join("\n")}")
exit MIQ_ABORT
end
This is great!! Any of you genius out there able to add a check for if the VM has a snapshot? If it does email the requestor stating the machine has a snapshot and this will need to be removed before expanding?!
This worked beautifully! Thank you!
Hi,
I am trying the have a vmware vm reconfigure option in service dialogue to change the CPU, Memory or Add additinal disk in end user selfservice portal. Any clue how can i achieve that.
I took this wonderful work and I tweaked it a bit and put it here, https://github.com/rhtconsulting/miq-Utilities/blob/master/Automate/RedHatConsulting_Utilities/Infrastructure/VM/Provisioning/StateMachines/Methods.class/methods/resize_disk.rb.
Thanks for the great work.
Blue skies,
Ian
Any chance you know how to do the same for RHV?
Unfortunately, no. We’ve only been focused on VMware implementations thus far so we haven’t looked at other providers.
``I couldn’t find a windows module for this, but I did put together some powershell to resize the partition and read a value sent over from cloudforms to let ansible know if the step is needed or not. (but I put some powershell logic in to check if there’s space left just in case)
---
# Written by Alex Mayberry, Red Hat (March, 2018)
#
# This role is designed to read the resize_p_drive = [true|false] from cloudforms
# if resize_p_drive == true, we need to log in and extend the p drive partition/filesystem to 100% of available space
#
# No Modules Were Harmed During the Creation of This Role
# Module Docs:
# http://docs.ansible.com/ansible/latest/win_command_module.html
#
- name: 'Resize partition and filesystem of P: to 100% of available space, if needed.'
win_shell: |
$cur_size = $(Get-Partition -driveletter p).size
$max_size = $(get-partitionsupportedsize -driveletter P).sizemax
if ( $cur_size -lt $max_size ) {
Resize-Partition -DriveLetter P -Size $max_size
}
when: resize_p_drive