-
Notifications
You must be signed in to change notification settings - Fork 70
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
With this commit we implement whatever support for virtual hardware reconfiguration. Namely, we support following operations for VM: - increase/decrease memory - increase/decrease number of cpu cores and sockets - increase disk size - add/remove disk We also update refresh parser to fetch correct data for disks. Signed-off-by: Miha Pleško <miha.plesko@xlab.si>
- Loading branch information
1 parent
153f893
commit b29d82e
Showing
5 changed files
with
240 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
63 changes: 63 additions & 0 deletions
63
app/models/manageiq/providers/vmware/cloud_manager/vm/reconfigure.rb
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
module ManageIQ::Providers::Vmware::CloudManager::Vm::Reconfigure | ||
# Show Reconfigure VM task | ||
def reconfigurable? | ||
true | ||
end | ||
|
||
def max_cpu_cores_per_socket(_total_vcpus = nil) | ||
128 | ||
end | ||
|
||
def max_total_vcpus | ||
128 | ||
end | ||
|
||
def max_vcpus | ||
128 | ||
end | ||
|
||
def max_memory_mb | ||
4.terabyte / 1.megabyte | ||
end | ||
|
||
def validate_config_spec(options) | ||
if vm_powered_on? | ||
if options[:number_of_cpus] | ||
number_of_cpus = options[:number_of_cpus].to_i | ||
cores_per_socket = options[:cores_per_socket].to_i | ||
raise MiqException::MiqVmError, 'CPU Hot-Add not enabled' if number_of_cpus != cpu_total_cores && !cpu_hot_add_enabled | ||
raise MiqException::MiqVmError, 'CPU Hot-Remove not enabled' if number_of_cpus < cpu_total_cores && !cpu_hot_remove_enabled | ||
raise MiqException::MiqVmError, 'Cannot change CPU cores per socket on a running VM' if cores_per_socket != cpu_cores_per_socket | ||
end | ||
|
||
if options[:vm_memory] | ||
vm_memory = options[:vm_memory].to_i | ||
raise MiqException::MiqVmError, 'Memory Hot-Add not enabled' if vm_memory > ram_size && !memory_hot_add_enabled | ||
raise MiqException::MiqVmError, 'Cannot remove memory from a running VM' if vm_memory < ram_size | ||
end | ||
end | ||
end | ||
|
||
def build_config_spec(options) | ||
validate_config_spec(options) | ||
|
||
# Virtual hardware modifications. | ||
new_hw = {} | ||
new_hw[:memory] = { :quantity_mb => options[:vm_memory] } if options[:vm_memory] | ||
new_hw[:cpu] = { :num_cores => options[:number_of_cpus], :cores_per_socket => options[:cores_per_socket] } if options[:number_of_cpus] | ||
if (%i(disk_add disk_resize disk_remove) & options.keys).any? | ||
new_hw[:disk] = [] | ||
Array(options[:disk_add]) .each_with_object(new_hw[:disk]) { |d, res| res << { :capacity_mb => d[:disk_size_in_mb].to_i } } | ||
Array(options[:disk_resize]).each_with_object(new_hw[:disk]) { |d, res| res << { :id => disk_id(d[:disk_name]), :capacity_mb => d[:disk_size_in_mb].to_i } } | ||
Array(options[:disk_remove]).each_with_object(new_hw[:disk]) { |d, res| res << { :id => disk_id(d[:disk_name]), :capacity_mb => -1 } } | ||
end | ||
|
||
new_hw.empty? ? {} : { :hardware => new_hw } | ||
end | ||
|
||
def disk_id(disk_name) | ||
disk = disks.detect { |d| d.filename == disk_name } | ||
# Disk location is stored as "{addr}/{parent_addr}/{disk_id}" e.g. "0/3/2000" | ||
disk.location.to_s.split('/').last | ||
end | ||
end |
140 changes: 140 additions & 0 deletions
140
spec/models/manageiq/providers/vmware/cloud_manager/vm/reconfigure_spec.rb
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,140 @@ | ||
describe ManageIQ::Providers::Vmware::CloudManager::Vm::Reconfigure do | ||
let(:vm) do | ||
FactoryGirl.create( | ||
:vm_vmware_cloud, | ||
:name => 'test_vm', | ||
:raw_power_state => 'off', | ||
:cpu_hot_add_enabled => true, | ||
:cpu_hot_remove_enabled => true, | ||
:memory_hot_add_enabled => true, | ||
:hardware => FactoryGirl.create( | ||
:hardware, | ||
:cpu4x2, | ||
:ram1GB, | ||
:disks => [ | ||
FactoryGirl.create(:disk, :size => 1024, :filename => 'Disk 0', :location => '0/1/2000'), | ||
FactoryGirl.create(:disk, :size => 2048, :filename => 'Disk 1', :location => '0/2/2001'), | ||
] | ||
) | ||
) | ||
end | ||
|
||
it '#reconfigurable?' do | ||
expect(vm.reconfigurable?).to be_truthy | ||
end | ||
|
||
describe '#build_config_spec' do | ||
let(:fog_options) { vm.build_config_spec(options) } | ||
let(:options) do | ||
{ | ||
:vm_memory => 16_384, | ||
:cores_per_socket => 2, | ||
:number_of_cpus => 16, | ||
:disk_add => [{ :disk_size_in_mb => '4096' }], | ||
:disk_resize => [{ :disk_name => 'Disk 0', :disk_size_in_mb => '6144' }], | ||
:disk_remove => [{ :disk_name => 'Disk 1' }], | ||
} | ||
end | ||
|
||
describe 'no hardware changes' do | ||
let(:options) { {} } | ||
|
||
it 'fog request optimized' do | ||
expect(fog_options).to eq({}) | ||
end | ||
end | ||
|
||
context 'VM off' do | ||
it 'memory' do | ||
expect(fog_options[:hardware][:memory][:quantity_mb]).to eq(16_384) | ||
end | ||
|
||
describe 'cpu' do | ||
it 'num_cores' do | ||
expect(fog_options[:hardware][:cpu][:num_cores]).to eq(16) | ||
end | ||
|
||
it 'cores_per_socket' do | ||
expect(fog_options[:hardware][:cpu][:cores_per_socket]).to eq(2) | ||
end | ||
end | ||
|
||
describe 'disks' do | ||
it 'add' do | ||
expect(fog_options[:hardware][:disk]).to include(:capacity_mb => 4096) | ||
end | ||
|
||
it 'resize' do | ||
expect(fog_options[:hardware][:disk]).to include(:id => '2000', :capacity_mb => 6144) | ||
end | ||
|
||
it 'remove' do | ||
expect(fog_options[:hardware][:disk]).to include(:id => '2001', :capacity_mb => -1) | ||
end | ||
end | ||
end | ||
|
||
context 'VM on' do | ||
before do | ||
vm.raw_power_state = 'on' | ||
end | ||
|
||
describe 'memory' do | ||
it 'add memory' do | ||
expect(fog_options[:hardware][:memory][:quantity_mb]).to eq(16_384) | ||
end | ||
|
||
it 'remove memory' do | ||
options[:vm_memory] = 512 | ||
expect { fog_options }.to raise_error(MiqException::MiqVmError, 'Cannot remove memory from a running VM') | ||
end | ||
end | ||
|
||
describe 'cpu' do | ||
it 'add cores' do | ||
expect(fog_options[:hardware][:cpu][:num_cores]).to eq(16) | ||
end | ||
|
||
it 'add cores per socket' do | ||
expect(fog_options[:hardware][:cpu][:cores_per_socket]).to eq(2) | ||
end | ||
|
||
it 'remove cores per socket' do | ||
options[:cores_per_socket] = 1 | ||
expect { fog_options }.to raise_error(MiqException::MiqVmError, 'Cannot change CPU cores per socket on a running VM') | ||
end | ||
end | ||
|
||
describe 'hot memory disabled' do | ||
before do | ||
vm.memory_hot_add_enabled = false | ||
end | ||
|
||
it 'add memory' do | ||
expect { fog_options }.to raise_error(MiqException::MiqVmError, 'Memory Hot-Add not enabled') | ||
end | ||
end | ||
|
||
describe 'hot cpu add disabled' do | ||
before do | ||
vm.cpu_hot_add_enabled = false | ||
end | ||
|
||
it 'add cores' do | ||
expect { fog_options }.to raise_error(MiqException::MiqVmError, 'CPU Hot-Add not enabled') | ||
end | ||
end | ||
|
||
describe 'hot cpu remove disabled' do | ||
before do | ||
vm.cpu_hot_remove_enabled = false | ||
end | ||
|
||
it 'remove cores' do | ||
options[:number_of_cpus] = 1 | ||
expect { fog_options }.to raise_error(MiqException::MiqVmError, 'CPU Hot-Remove not enabled') | ||
end | ||
end | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters