|
|
|
|
@@ -14,87 +14,94 @@ describe VagrantPlugins::ProviderLibvirt::Driver do
|
|
|
|
|
|
|
|
|
|
subject { described_class.new(machine) }
|
|
|
|
|
|
|
|
|
|
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") }
|
|
|
|
|
|
|
|
|
|
# make it easier for distros that want to switch the default value for
|
|
|
|
|
# qemu_use_session to true by ensuring it is explicitly false for tests.
|
|
|
|
|
before do
|
|
|
|
|
allow(machine.provider_config).to receive(:qemu_use_session).and_return(false)
|
|
|
|
|
allow(logger).to receive(:info)
|
|
|
|
|
allow(logger).to receive(:debug)
|
|
|
|
|
allow(machine.provider).to receive('driver').and_call_original
|
|
|
|
|
allow(machine2.provider).to receive('driver').and_call_original
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
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)
|
|
|
|
|
describe 'connections' do
|
|
|
|
|
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
|
|
|
|
|
|
|
|
|
|
it 'should configure the connection once' do
|
|
|
|
|
expect(Fog::Compute).to receive(:new).once().and_return(connection1)
|
|
|
|
|
# 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") }
|
|
|
|
|
|
|
|
|
|
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_read_only).with('qemu+ssh://user@remote1/system').and_return(system_connection1)
|
|
|
|
|
expect(Libvirt).to receive(:open_read_only).with('qemu+ssh://vms@remote2/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)
|
|
|
|
|
# make it easier for distros that want to switch the default value for
|
|
|
|
|
# qemu_use_session to true by ensuring it is explicitly false for tests.
|
|
|
|
|
before do
|
|
|
|
|
allow(machine.provider).to receive('driver').and_call_original
|
|
|
|
|
allow(machine2.provider).to receive('driver').and_call_original
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
it 'should configure the connection once' do
|
|
|
|
|
expect(Libvirt).to receive(:open_read_only).with('qemu+ssh://user@remote1/system').and_return(system_connection1)
|
|
|
|
|
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.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)
|
|
|
|
|
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_read_only).with('qemu+ssh://user@remote1/system').and_return(system_connection1)
|
|
|
|
|
expect(Libvirt).to receive(:open_read_only).with('qemu+ssh://vms@remote2/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_read_only).with('qemu+ssh://user@remote1/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
|
|
|
|
|
|
|
|
|
|
@@ -179,6 +186,7 @@ describe VagrantPlugins::ProviderLibvirt::Driver do
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
context 'when qemu_use_session is enabled' do
|
|
|
|
|
let(:system_connection) { double("system connection") }
|
|
|
|
|
let(:networks) { [instance_double(::Fog::Libvirt::Compute::Real)] }
|
|
|
|
|
let(:dhcp_leases) {
|
|
|
|
|
{
|
|
|
|
|
@@ -199,8 +207,8 @@ describe VagrantPlugins::ProviderLibvirt::Driver do
|
|
|
|
|
|
|
|
|
|
it 'should retrieve the address via the system dhcp-leases API' do
|
|
|
|
|
expect(domain).to receive(:mac).and_return("52:54:00:8b:dc:5f")
|
|
|
|
|
expect(subject).to receive(:system_connection).and_return(system_connection1)
|
|
|
|
|
expect(system_connection1).to receive(:list_all_networks).and_return(networks)
|
|
|
|
|
expect(subject).to receive(:system_connection).and_return(system_connection)
|
|
|
|
|
expect(system_connection).to receive(:list_all_networks).and_return(networks)
|
|
|
|
|
expect(networks[0]).to receive(:dhcp_leases).and_return([dhcp_leases])
|
|
|
|
|
|
|
|
|
|
expect(subject.get_ipaddress).to eq("192.168.122.43")
|
|
|
|
|
@@ -221,6 +229,99 @@ describe VagrantPlugins::ProviderLibvirt::Driver do
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
describe '#host_devices' do
|
|
|
|
|
let(:vagrantfile_providerconfig) do
|
|
|
|
|
<<-EOF
|
|
|
|
|
libvirt.uri = "qemu:///system"
|
|
|
|
|
EOF
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
let(:ip_link_show) {
|
|
|
|
|
JSON.dump(
|
|
|
|
|
[
|
|
|
|
|
# trimmed element details of what would be returned by 'ip -j link show'
|
|
|
|
|
{ "ifindex": 1, "ifname": "lo", "group": "default", "link_type": "loopback"},
|
|
|
|
|
{ "ifindex": 2, "ifname": "eth0", "group": "default", "link_type": "ether"},
|
|
|
|
|
{ "ifindex": 3, "ifname": "eth1", "group": "default", "link_type": "ether"},
|
|
|
|
|
{ "ifindex": 4, "ifname": "virbr0", "group": "default", "link_type": "ether"},
|
|
|
|
|
]
|
|
|
|
|
)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
let(:libvirt_interfaces) { [
|
|
|
|
|
instance_double(Libvirt::Interface),
|
|
|
|
|
instance_double(Libvirt::Interface),
|
|
|
|
|
] }
|
|
|
|
|
let(:libvirt_networks) { [
|
|
|
|
|
instance_double(Libvirt::Network),
|
|
|
|
|
instance_double(Libvirt::Network),
|
|
|
|
|
] }
|
|
|
|
|
|
|
|
|
|
before do
|
|
|
|
|
allow(subject).to receive(:connection).and_return(connection)
|
|
|
|
|
|
|
|
|
|
allow(Vagrant::Util::Subprocess).to receive(:execute) do |*arr|
|
|
|
|
|
expect(arr[0]).to eq('ip')
|
|
|
|
|
end.and_return(Vagrant::Util::Subprocess::Result.new(exit_code=0, stdout=ip_link_show, stderr=''))
|
|
|
|
|
|
|
|
|
|
expect(libvirt_client).to receive(:list_all_interfaces).and_return(libvirt_interfaces)
|
|
|
|
|
expect(libvirt_client).to receive(:list_all_networks).and_return(libvirt_networks)
|
|
|
|
|
expect(libvirt_interfaces[0]).to receive(:name).and_return('eth0')
|
|
|
|
|
expect(libvirt_interfaces[1]).to receive(:name).and_return('virbr0')
|
|
|
|
|
expect(libvirt_networks[0]).to receive(:bridge_name).and_return('')
|
|
|
|
|
expect(libvirt_networks[1]).to receive(:bridge_name).and_return('virbr0')
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
it 'should query system and libvirt' do
|
|
|
|
|
expect(subject.host_devices).to eq(['lo', 'eth0', 'eth1', 'virbr0'])
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
it 'should handle empty string' do
|
|
|
|
|
expect(machine.provider_config).to receive(:proxy_command).and_return('').twice
|
|
|
|
|
|
|
|
|
|
expect(subject.host_devices).to eq(['lo', 'eth0', 'eth1', 'virbr0'])
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
it 'should cache the result' do
|
|
|
|
|
expect(machine.provider_config).to receive(:proxy_command).and_return(nil).once
|
|
|
|
|
|
|
|
|
|
expect(subject.host_devices).to eq(['lo', 'eth0', 'eth1', 'virbr0'])
|
|
|
|
|
expect(subject.host_devices).to eq(['lo', 'eth0', 'eth1', 'virbr0'])
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
context 'when libvirt is remote' do
|
|
|
|
|
let(:vagrantfile_providerconfig) do
|
|
|
|
|
<<-EOF
|
|
|
|
|
libvirt.uri = "qemu+ssh://remote-server/system"
|
|
|
|
|
EOF
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
before do
|
|
|
|
|
allow(machine.provider_config).to receive(:proxy_command).and_return('ssh remote-server -W %h:%p')
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
it 'should use ssh for ip link' do
|
|
|
|
|
expect(Vagrant::Util::Subprocess).to receive(:execute) do |*arr|
|
|
|
|
|
expect(arr[0..3]).to eq(['ssh', 'remote-server', 'ip', '-j'])
|
|
|
|
|
end.and_return(Vagrant::Util::Subprocess::Result.new(exit_code=0, stdout=ip_link_show, stderr=''))
|
|
|
|
|
|
|
|
|
|
expect(subject.host_devices).to eq(['lo', 'eth0', 'eth1', 'virbr0'])
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
it 'should construct the ssh command with all options when needed' do
|
|
|
|
|
machine.provider_config.port = 2022
|
|
|
|
|
machine.provider_config.username = 'remote-user'
|
|
|
|
|
machine.provider_config.id_ssh_key_file = 'my-key-file'
|
|
|
|
|
|
|
|
|
|
expect(Vagrant::Util::Subprocess).to receive(:execute) do |*arr|
|
|
|
|
|
expect(arr[0..9]).to eq(['ssh', 'remote-server', '-p', '2022', '-l', 'remote-user', '-i', 'my-key-file', 'ip', '-j'])
|
|
|
|
|
end.and_return(Vagrant::Util::Subprocess::Result.new(exit_code=0, stdout=ip_link_show, stderr=''))
|
|
|
|
|
|
|
|
|
|
expect(subject.host_devices).to eq(['lo', 'eth0', 'eth1', 'virbr0'])
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
describe '#state' do
|
|
|
|
|
let(:domain) { double('domain') }
|
|
|
|
|
|
|
|
|
|
|