Support provider URI per machine definition (#1363)

Save the variables on the instance to allow for different connection
settings to be specified on a per machine basis.

Provide some rudimentary tests that ensure that the different URIs are
used when constructing connections, and additionally the connection is
created only once, no matter how many times it is subsequently called.

Fixes: #1358
This commit is contained in:
Darragh Bailey
2021-09-27 18:11:29 +01:00
committed by GitHub
parent de4721f62e
commit 605aabcd98
2 changed files with 96 additions and 11 deletions

View File

@@ -8,13 +8,15 @@ require 'json'
module VagrantPlugins module VagrantPlugins
module ProviderLibvirt module ProviderLibvirt
class Driver class Driver
# store the connection at the process level # store the connection at the instance level as this will be per
# thread and allows for individual machines to use different
# connection settings.
# #
# possibly this should be a connection pool using the connection # possibly this should be a connection pool using the connection
# settings as a key to allow per machine connection attributes # settings as a key to allow identical connections to be reused
# to be used. # across machines.
@@connection = nil @connection = nil
@@system_connection = nil @system_connection = nil
def initialize(machine) def initialize(machine)
@logger = Log4r::Logger.new('vagrant_libvirt::driver') @logger = Log4r::Logger.new('vagrant_libvirt::driver')
@@ -24,7 +26,7 @@ module VagrantPlugins
def connection def connection
# If already connected to Libvirt, just use it and don't connect # If already connected to Libvirt, just use it and don't connect
# again. # again.
return @@connection if @@connection return @connection if @connection
# Get config options for Libvirt provider. # Get config options for Libvirt provider.
config = @machine.provider_config config = @machine.provider_config
@@ -43,24 +45,24 @@ module VagrantPlugins
@logger.info("Connecting to Libvirt (#{uri}) ...") @logger.info("Connecting to Libvirt (#{uri}) ...")
begin begin
@@connection = Fog::Compute.new(conn_attr) @connection = Fog::Compute.new(conn_attr)
rescue Fog::Errors::Error => e rescue Fog::Errors::Error => e
raise Errors::FogLibvirtConnectionError, raise Errors::FogLibvirtConnectionError,
error_message: e.message error_message: e.message
end end
@@connection @connection
end end
def system_connection def system_connection
# If already connected to Libvirt, just use it and don't connect # If already connected to Libvirt, just use it and don't connect
# again. # again.
return @@system_connection if @@system_connection return @system_connection if @system_connection
config = @machine.provider_config config = @machine.provider_config
@@system_connection = Libvirt::open(config.system_uri) @system_connection = Libvirt::open(config.system_uri)
@@system_connection @system_connection
end end
def get_domain(machine) def get_domain(machine)

83
spec/unit/driver_spec.rb Normal file
View File

@@ -0,0 +1,83 @@
# frozen_string_literal: true
require 'spec_helper'
require 'support/sharedcontext'
require 'vagrant-libvirt/driver'
describe VagrantPlugins::ProviderLibvirt::Driver do
include_context 'unit'
let(:vagrantfile) do
<<-EOF
Vagrant.configure('2') do |config|
config.vm.define :test1 do |node|
node.vm.provider :libvirt do |domain|
domain.uri = "qemu+ssh://user@remote1/system"
end
end
config.vm.define :test2 do |node|
node.vm.provider :libvirt do |domain|
domain.uri = "qemu+ssh://vms@remote2/system"
end
end
end
EOF
end
# need to override the default package iso_env as using a different
# name for the test machines above.
let(:machine) { iso_env.machine(:test1, :libvirt) }
let(:machine2) { iso_env.machine(:test2, :libvirt) }
let(:connection1) { double("connection 1") }
let(:connection2) { double("connection 2") }
let(:system_connection1) { double("system connection 1") }
let(:system_connection2) { double("system connection 2") }
describe '#connection' do
it 'should configure a separate connection per machine' do
expect(Fog::Compute).to receive(:new).with(
hash_including({:libvirt_uri => 'qemu+ssh://user@remote1/system'})).and_return(connection1)
expect(Fog::Compute).to receive(:new).with(
hash_including({:libvirt_uri => 'qemu+ssh://vms@remote2/system'})).and_return(connection2)
expect(machine.provider.driver.connection).to eq(connection1)
expect(machine2.provider.driver.connection).to eq(connection2)
end
it 'should configure the connection once' do
expect(Fog::Compute).to receive(:new).once().and_return(connection1)
expect(machine.provider.driver.connection).to eq(connection1)
expect(machine.provider.driver.connection).to eq(connection1)
expect(machine.provider.driver.connection).to eq(connection1)
end
end
describe '#system_connection' do
# note that the urls for the two tests are currently
# incorrect here as they should be the following:
# qemu+ssh://user@remote1/system
# qemu+ssh://vms@remote2/system
#
# In that the system uri should be resolved based on
# the provider uri so that for:
# uri => qemu+ssh://user@remote1/session
# system_uri should be 'qemu+ssh://user@remote1/system'
# and not 'qemu:///system'.
it 'should configure a separate connection per machine' do
expect(Libvirt).to receive(:open).with('qemu:///system').and_return(system_connection1)
expect(Libvirt).to receive(:open).with('qemu:///system').and_return(system_connection2)
expect(machine.provider.driver.system_connection).to eq(system_connection1)
expect(machine2.provider.driver.system_connection).to eq(system_connection2)
end
it 'should configure the connection once' do
expect(Libvirt).to receive(:open).with('qemu:///system').and_return(system_connection1)
expect(machine.provider.driver.system_connection).to eq(system_connection1)
expect(machine.provider.driver.system_connection).to eq(system_connection1)
expect(machine.provider.driver.system_connection).to eq(system_connection1)
end
end
end