diff --git a/lib/fog/xenserver/models/compute/server.rb b/lib/fog/xenserver/models/compute/server.rb index 526403e21..d3ac9b236 100644 --- a/lib/fog/xenserver/models/compute/server.rb +++ b/lib/fog/xenserver/models/compute/server.rb @@ -126,8 +126,8 @@ module Fog def save(params = {}) requires :name - networks = params[:networks] || [] - attributes = connection.get_record(connection.create_server( name, template_name, networks ), 'VM') + nets = attributes[:networks] || [] + attributes = connection.get_record(connection.create_server( name, template_name, nets ), 'VM') merge_attributes attributes true end diff --git a/lib/fog/xenserver/requests/compute/create_server.rb b/lib/fog/xenserver/requests/compute/create_server.rb index 989f72273..0f686cc9d 100644 --- a/lib/fog/xenserver/requests/compute/create_server.rb +++ b/lib/fog/xenserver/requests/compute/create_server.rb @@ -26,19 +26,15 @@ module Fog raise "Invalid template" end - #FIXME: need to check that template exist actually raise "Template #{template_string} does not exist" if template.allowed_operations.nil? raise 'Clone Operation not Allowed' unless template.allowed_operations.include?('clone') # Clone the VM template - ref = @connection.request( - {:parser => Fog::Parsers::XenServer::Base.new, :method => 'VM.clone'}, - template.reference, name_label - ) + ref = clone_server name_label, template.reference + # Add additional NICs networks.each do |n| create_vif ref, n.reference end - #new_vm = servers.get get_vm_by_name( name_label ) @connection.request({:parser => Fog::Parsers::XenServer::Base.new, :method => 'VM.provision'}, ref) start_vm( ref ) unless extra_args[:auto_start] == false diff --git a/lib/fog/xenserver/requests/compute/create_vif.rb b/lib/fog/xenserver/requests/compute/create_vif.rb index df6b2d368..ff71ad730 100644 --- a/lib/fog/xenserver/requests/compute/create_vif.rb +++ b/lib/fog/xenserver/requests/compute/create_vif.rb @@ -4,23 +4,41 @@ module Fog class Real - def create_vif( vm_ref, network_ref ) - vif_config = default_vif_config(vm_ref, network_ref) + def create_vif( vm_ref, network_ref, device = -1) + raise ArgumentError.new('Invalid vm_ref') if vm_ref.nil? + raise ArgumentError.new('Invalid network_ref') if network_ref.nil? + vif_config = default_vif_config(vm_ref, network_ref, device.to_s) @connection.request({:parser => Fog::Parsers::XenServer::Base.new, :method => 'VIF.create'}, vif_config ) end - - def default_vif_config( vm_ref, network_ref, device_number = '0' ) - { + + def create_vif_custom( conf ) + raise ArgumentError.new('VIF config is not a Hash') if not conf.kind_of?(Hash) + @connection.request({:parser => Fog::Parsers::XenServer::Base.new, :method => 'VIF.create'}, conf ) + end + + def default_vif_config( vm_ref, network_ref, device_number = '-1' ) + conf = { 'MAC_autogenerated' => 'True', 'VM' => vm_ref, 'network' => network_ref, - 'device' => device_number, 'MAC' => '', 'MTU' => '0', 'other_config' => {}, 'qos_algorithm_type' => 'ratelimit', 'qos_algorithm_params' => {} } + if device_number.to_i >= 0 + conf['device'] = device_number + else + highest_dev = 0 + server = servers.get vm_ref + server.vifs.each do |vif| + dev = vif.device.to_i + highest_dev = dev if dev > highest_dev + end + conf['device'] = (highest_dev + 1).to_s + end + conf end end diff --git a/tests/xenserver/models/compute/server_tests.rb b/tests/xenserver/models/compute/server_tests.rb index b3359040e..07c375a15 100644 --- a/tests/xenserver/models/compute/server_tests.rb +++ b/tests/xenserver/models/compute/server_tests.rb @@ -70,21 +70,22 @@ Shindo.tests('Fog::Compute[:xenserver] | server model', ['xenserver']) do tests("Creating a server") do tests("it should create a server") do s = nil - test("named FOOBARSTUFF") do - s = servers.create(:name => "FOOBARSTUFF", + test("named #{test_ephemeral_vm_name}") do + s = servers.create(:name => test_ephemeral_vm_name, :template_name => test_template_name) - servers.get(s.reference).name == "FOOBARSTUFF" + servers.get(s.reference).name == test_ephemeral_vm_name end test("and destroy it afterwards") { s.destroy } end tests("it should create a server") do s = nil - test("with 3 NICs") do - s = servers.create(:name => "FOOBARSTUFF", + # The template has 2 VIFs already, we add 2 more + test("with 4 NICs") do + s = servers.create(:name => test_ephemeral_vm_name, :template_name => test_template_name, - :networks => [connection.default_network, connection.default_network, connection.default_network]) + :networks => [connection.default_network, connection.default_network]) s.reload - s.networks.size == 3 + s.networks.size == 4 end test("and destroy it afterwards") { s.destroy } end diff --git a/tests/xenserver/requests/compute/create_vif_tests.rb b/tests/xenserver/requests/compute/create_vif_tests.rb new file mode 100644 index 000000000..8b1d56a01 --- /dev/null +++ b/tests/xenserver/requests/compute/create_vif_tests.rb @@ -0,0 +1,88 @@ +Shindo.tests('Fog::Compute[:xenserver] | create_vif request', ['xenserver']) do + + compute = Fog::Compute[:xenserver] + servers = compute.servers + # pre-flight cleanup + (servers.all :name_matches => test_ephemeral_vm_name).each do |s| + s.destroy + end + + tests('create_vif should') do + vm_ref = compute.create_server test_ephemeral_vm_name, test_template_name + ref = compute.create_vif vm_ref, compute.networks.first.reference + s = servers.get vm_ref + test('return a valid reference') do + if (ref != "OpaqueRef:NULL") and (ref.split("1") != "NULL") + true + else + false + end + end + test('add the VIF to the server') do + !(s.vifs.find { |vif| vif.reference == ref }).nil? + end + raises(ArgumentError, 'raise ArgumentError when vm_ref nil') do + ref = compute.create_vif nil, compute.networks.first.reference + end + raises(ArgumentError, 'raise ArgumentError when network_ref nil') do + ref = compute.create_vif vm_ref, nil + end + test('create a VIF with device number 9') do + ref = compute.create_vif vm_ref, compute.networks.first.reference, 9 + s.reload + (compute.vifs.get(ref).device == 9.to_s) and \ + !(s.vifs.find { |vif| vif.reference == ref }).nil? + end + end + + tests('create_vif_custom should') do + vm_ref = compute.create_server test_ephemeral_vm_name, test_template_name + network_ref = compute.networks.first.reference + conf = { + 'MAC_autogenerated' => 'True', + 'VM' => vm_ref, + 'network' => network_ref, + 'MAC' => '', + 'device' => '4', + 'MTU' => '0', + 'other_config' => {}, + 'qos_algorithm_type' => 'ratelimit', + 'qos_algorithm_params' => {} + } + ref = compute.create_vif_custom conf + s = servers.get vm_ref + test('return a valid reference') do + if (ref != "OpaqueRef:NULL") and (ref.split("1") != "NULL") + true + else + false + end + end + test('add the VIF to the server') do + !(s.vifs.find { |vif| vif.reference == ref }).nil? + end + raises(ArgumentError, 'raise ArgumentError when conf is not a Hash') do + conf['device'] = '5' + ref = compute.create_vif_custom 'foobar' + end + test('create a VIF with device number 9') do + conf['device'] = '9' + ref = compute.create_vif_custom conf + s.reload + (compute.vifs.get(ref).device == 9.to_s) and \ + !(s.vifs.find { |vif| vif.reference == ref }).nil? + end + test('create a VIF with MAC 11:22:33:44:55:66') do + conf['MAC_autogenerated'] = 'False' + conf['MAC'] = '11:22:33:44:55:66' + conf['device'] = '6' + ref = compute.create_vif_custom conf + vif = compute.vifs.get ref + vif.mac == '11:22:33:44:55:66' + end + end + + tests('The expected options') do + raises(ArgumentError, 'raises ArgumentError when vm_ref,net_ref missing') { compute.create_vif } + end +end