Skip to content

Commit 12c8aa3

Browse files
authored
Merge pull request #894 from Dhamo1107/add-volume-to-root-disk
Add the volume to the root disk (vda) if the selected flavor has a ro…
2 parents 4959c79 + b5f9b0f commit 12c8aa3

File tree

2 files changed

+72
-44
lines changed

2 files changed

+72
-44
lines changed

app/models/manageiq/providers/openstack/cloud_manager/provision/volume_attachment.rb

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,18 @@
11
module ManageIQ::Providers::Openstack::CloudManager::Provision::VolumeAttachment
22
def create_requested_volumes(requested_volumes)
3-
volumes_attrs_list = [default_volume_attributes]
3+
volumes_attrs_list = instance_type.root_disk_size > 0 ? [default_volume_attributes] : []
44

55
connection_options = {:service => "volume", :tenant_name => cloud_tenant.try(:name)}
66
source.ext_management_system.with_provider_connection(connection_options) do |service|
7-
requested_volumes.each do |volume_attrs|
7+
requested_volumes.each_with_index do |volume_attrs, index|
8+
if instance_type.root_disk_size == 0 # Handle root disk logic only when root_disk_size is 0
9+
if index == 0 # The first volume should be the root disk, typically assigned to vda
10+
volume_attrs[:imageRef] = source.ems_ref # Set the image reference for booting
11+
volume_attrs[:bootable] = true
12+
volume_attrs[:boot_index] = 0
13+
end
14+
end
15+
816
new_volume_id = service.volumes.create(volume_attrs).id
917
new_volume_attrs = volume_attrs.clone
1018
new_volume_attrs[:uuid] = new_volume_id
Lines changed: 62 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1,82 +1,102 @@
11
describe ManageIQ::Providers::Openstack::CloudManager::Provision::VolumeAttachment do
2-
before do
3-
@ems = FactoryBot.create(:ems_openstack_with_authentication)
4-
@template = FactoryBot.create(:template_openstack, :ext_management_system => @ems)
5-
@flavor = FactoryBot.create(:flavor_openstack)
6-
@volume = FactoryBot.create(:cloud_volume_openstack)
2+
let(:ems) { FactoryBot.create(:ems_openstack_with_authentication) }
3+
let(:flavor) { FactoryBot.create(:flavor_openstack) }
4+
let(:template) { FactoryBot.create(:template_openstack, :ext_management_system => ems) }
5+
let(:volume) { FactoryBot.create(:cloud_volume_openstack) }
6+
let(:service) { double("volume service") }
7+
let(:task_options) { {:instance_type => flavor, :src_vm_id => template.id, :volumes => task_volumes} }
8+
let(:task_volumes) { [{:name => "custom_volume_1", :size => 2}] }
9+
let(:task) { FactoryBot.create(:miq_provision_openstack, :source => template, :state => 'pending', :status => 'Ok', :options => task_options) }
710

11+
before do
812
# We're storing objects in the instance_type, so we must permit loading this class
9-
ActiveRecord.yaml_column_permitted_classes = YamlPermittedClasses.app_yaml_permitted_classes | [@flavor.class]
10-
11-
@task = FactoryBot.create(:miq_provision_openstack,
12-
:source => @template,
13-
:state => 'pending',
14-
:status => 'Ok',
15-
:options => {
16-
:instance_type => @flavor,
17-
:src_vm_id => @template.id,
18-
:volumes => [{:name => "custom_volume_1", :size => 2}]
19-
})
13+
ActiveRecord.yaml_column_permitted_classes = YamlPermittedClasses.app_yaml_permitted_classes | [flavor.class]
2014
end
2115

2216
context "#configure_volumes" do
23-
it "create volumes" do
24-
service = double
25-
allow(service).to receive_message_chain('volumes.create').and_return @volume
26-
allow(@task.source.ext_management_system).to receive(:with_provider_connection)\
17+
before do
18+
allow(service).to receive_message_chain(:volumes, :create).and_return(volume)
19+
allow(task.source.ext_management_system).to receive(:with_provider_connection)
2720
.with({:service => 'volume', :tenant_name => nil}).and_yield(service)
28-
allow(@task).to receive(:instance_type).and_return @flavor
21+
allow(task).to receive(:instance_type).and_return(flavor)
22+
end
2923

24+
it "create volumes" do
3025
default_volume = {:name => "root", :size => 1, :source_type => "image", :destination_type => "local",
3126
:boot_index => 0, :delete_on_termination => true, :uuid => nil}
32-
requested_volume = {:name => "custom_volume_1", :size => 2, :uuid => @volume.id, :source_type => "volume",
27+
requested_volume = {:name => "custom_volume_1", :size => 2, :uuid => volume.id, :source_type => "volume",
3328
:destination_type => "volume"}
3429

35-
expect(@task.create_requested_volumes(@task.options[:volumes])).to eq [default_volume, requested_volume]
30+
expect(task.create_requested_volumes(task.options[:volumes])).to eq([default_volume, requested_volume])
31+
end
32+
33+
context "with a flavor that has no root disk" do
34+
let(:flavor) { FactoryBot.create(:flavor_openstack, :root_disk_size => 0) }
35+
36+
it "sets the requested volume as a boot disk" do
37+
expected_volume = {:name => "custom_volume_1", :size => 2, :uuid => volume.id, :source_type => "volume",
38+
:destination_type => "volume", :boot_index => 0, :bootable => true, :imageRef => template.ems_ref}
39+
40+
expect(task.create_requested_volumes(task.options[:volumes])).to eq([expected_volume])
41+
end
42+
43+
context "with multiple requested volumes" do
44+
let(:task_volumes) { [{:name => "custom_volume_1", :size => 2}, {:name => "custom_volume_2", :size => 4}] }
45+
46+
it "only sets boot_index for first volumes" do
47+
expected_volume_1 = {:name => "custom_volume_1", :size => 2, :uuid => volume.id, :source_type => "volume",
48+
:destination_type => "volume", :boot_index => 0, :bootable => true, :imageRef => template.ems_ref}
49+
expected_volume_2 = {:name => "custom_volume_2", :size => 4, :uuid => volume.id, :source_type => "volume",
50+
:destination_type => "volume"}
51+
52+
expect(task.create_requested_volumes(task.options[:volumes])).to eq([expected_volume_1, expected_volume_2])
53+
end
54+
end
3655
end
3756
end
3857

3958
context "#check_volumes" do
4059
it "status pending" do
4160
pending_volume_attrs = {:source_type => "volume"}
42-
service = double
43-
allow(service).to receive_message_chain('volumes.get').and_return FactoryBot.build(:cloud_volume_openstack,
44-
:status => "pending")
45-
allow(@task.source.ext_management_system).to receive(:with_provider_connection)\
61+
62+
allow(service).to receive_message_chain('volumes.get')
63+
.and_return(FactoryBot.build(:cloud_volume_openstack, :status => "pending"))
64+
allow(task.source.ext_management_system).to receive(:with_provider_connection)
4665
.with({:service => 'volume', :tenant_name => nil}).and_yield(service)
4766

48-
expect(@task.do_volume_creation_check([pending_volume_attrs])).to eq [false, "pending"]
67+
expect(task.do_volume_creation_check([pending_volume_attrs])).to eq([false, "pending"])
4968
end
5069

5170
it "check creation status available" do
5271
pending_volume_attrs = {:source_type => "volume"}
53-
service = double
54-
allow(service).to receive_message_chain('volumes.get').and_return FactoryBot.build(:cloud_volume_openstack,
55-
:status => "available")
56-
allow(@task.source.ext_management_system).to receive(:with_provider_connection)\
72+
73+
allow(service).to receive_message_chain('volumes.get')
74+
.and_return(FactoryBot.build(:cloud_volume_openstack, :status => "available"))
75+
allow(task.source.ext_management_system).to receive(:with_provider_connection)
5776
.with({:service => 'volume', :tenant_name => nil}).and_yield(service)
5877

59-
expect(@task.do_volume_creation_check([pending_volume_attrs])).to eq true
78+
expect(task.do_volume_creation_check([pending_volume_attrs])).to be_truthy
6079
end
6180

6281
it "check creation status - not found" do
6382
pending_volume_attrs = {:source_type => "volume"}
64-
service = double
65-
allow(service).to receive_message_chain('volumes.get').and_return nil
66-
allow(@task.source.ext_management_system).to receive(:with_provider_connection)\
83+
84+
allow(service).to receive_message_chain('volumes.get').and_return(nil)
85+
allow(task.source.ext_management_system).to receive(:with_provider_connection)
6786
.with({:service => 'volume', :tenant_name => nil}).and_yield(service)
6887

69-
expect(@task.do_volume_creation_check([pending_volume_attrs])).to eq [false, nil]
88+
expect(task.do_volume_creation_check([pending_volume_attrs])).to eq([false, nil])
7089
end
7190

7291
it "status error" do
7392
pending_volume_attrs = {:source_type => "volume"}
74-
service = double
75-
allow(service).to receive_message_chain('volumes.get').and_return FactoryBot.build(:cloud_volume_openstack,
76-
:status => "error")
77-
allow(@task.source.ext_management_system).to receive(:with_provider_connection)\
93+
94+
allow(service).to receive_message_chain('volumes.get')
95+
.and_return(FactoryBot.build(:cloud_volume_openstack, :status => "error"))
96+
allow(task.source.ext_management_system).to receive(:with_provider_connection)
7897
.with({:service => 'volume', :tenant_name => nil}).and_yield(service)
79-
expect { @task.do_volume_creation_check([pending_volume_attrs]) }.to raise_error(MiqException::MiqProvisionError)
98+
99+
expect { task.do_volume_creation_check([pending_volume_attrs]) }.to raise_error(MiqException::MiqProvisionError)
80100
end
81101
end
82102
end

0 commit comments

Comments
 (0)