From f6992fd8481a4f2eaa026bfdf8670f55b9a820ba Mon Sep 17 00:00:00 2001 From: Rui Lopes Date: Thu, 22 Sep 2022 11:40:17 +0100 Subject: [PATCH] fix qemu_use_agent to work with windows guests (#1599) When using `qemu_use_agent = true`, the provisioning of a Windows machine was faling to get the IP address with the error: ``` `get_ipaddress_from_qemu_agent': undefined method `downcase' for nil:NilClass (NoMethodError) ``` ```plain Traceback (most recent call last): 18: from /opt/vagrant/embedded/gems/2.3.0/gems/logging-2.3.1/lib/logging/diagnostic_context.rb:474:in `block in create_with_logging_context' 17: from /opt/vagrant/embedded/gems/2.3.0/gems/vagrant-2.3.0/lib/vagrant/action/builtin/wait_for_communicator.rb:16:in `block in call' 16: from /opt/vagrant/embedded/gems/2.3.0/gems/vagrant-2.3.0/plugins/communicators/winrm/communicator.rb:31:in `wait_for_ready' 15: from /opt/vagrant/embedded/lib/ruby/2.7.0/timeout.rb:110:in `timeout' 14: from /opt/vagrant/embedded/lib/ruby/2.7.0/timeout.rb:33:in `catch' 13: from /opt/vagrant/embedded/lib/ruby/2.7.0/timeout.rb:33:in `catch' 12: from /opt/vagrant/embedded/lib/ruby/2.7.0/timeout.rb:33:in `block in catch' 11: from /opt/vagrant/embedded/lib/ruby/2.7.0/timeout.rb:95:in `block in timeout' 10: from /opt/vagrant/embedded/gems/2.3.0/gems/vagrant-2.3.0/plugins/communicators/winrm/communicator.rb:37:in `block in wait_for_ready' 9: from /opt/vagrant/embedded/gems/2.3.0/gems/vagrant-2.3.0/plugins/communicators/winrm/helper.rb:21:in `winrm_info' 8: from /opt/vagrant/embedded/gems/2.3.0/gems/vagrant-2.3.0/plugins/communicators/winrm/helper.rb:35:in `winrm_address' 7: from /opt/vagrant/embedded/gems/2.3.0/gems/vagrant-2.3.0/lib/vagrant/machine.rb:452:in `ssh_info' 6: from /home/rgl/.vagrant.d/gems/2.7.6/gems/vagrant-libvirt-0.10.7/lib/vagrant-libvirt/provider.rb:58:in `ssh_info' 5: from /home/rgl/.vagrant.d/gems/2.7.6/gems/vagrant-libvirt-0.10.7/lib/vagrant-libvirt/provider.rb:98:in `state' 4: from /home/rgl/.vagrant.d/gems/2.7.6/gems/vagrant-libvirt-0.10.7/lib/vagrant-libvirt/driver.rb:194:in `state' 3: from /home/rgl/.vagrant.d/gems/2.7.6/gems/vagrant-libvirt-0.10.7/lib/vagrant-libvirt/driver.rb:103:in `get_domain_ipaddress' 2: from /home/rgl/.vagrant.d/gems/2.7.6/gems/vagrant-libvirt-0.10.7/lib/vagrant-libvirt/driver.rb:242:in `get_ipaddress_from_qemu_agent' 1: from /home/rgl/.vagrant.d/gems/2.7.6/gems/vagrant-libvirt-0.10.7/lib/vagrant-libvirt/driver.rb:242:in `each' /home/rgl/.vagrant.d/gems/2.7.6/gems/vagrant-libvirt-0.10.7/lib/vagrant-libvirt/driver.rb:243:in `block in get_ipaddress_from_qemu_agent': undefined method `downcase' for nil:NilClass (NoMethodError) ``` This is due to Windows qemu-ga reporting interfaces that do not have a `hardware-address`. For example, the `Loopback Pseudo-Interface 1` does not have it: ```console $ virsh qemu-agent-command openwrt-vagrant-windows '{"execute":"guest-network-get-interfaces"}' --pretty { "return": [ { "name": "Ethernet 2", "ip-addresses": [ { "ip-address-type": "ipv4", "ip-address": "10.0.20.11", "prefix": 24 } ], "statistics": { "tx-packets": 3090, "tx-errs": 0, "rx-bytes": 50713786, "rx-dropped": 0, "rx-packets": 35116, "rx-errs": 0, "tx-bytes": 744040, "tx-dropped": 0 }, "hardware-address": "08:00:27:00:00:0b" }, { "name": "Loopback Pseudo-Interface 1", "ip-addresses": [ { "ip-address-type": "ipv6", "ip-address": "::1", "prefix": 128 }, { "ip-address-type": "ipv4", "ip-address": "127.0.0.1", "prefix": 8 } ], "statistics": { "tx-packets": 0, "tx-errs": 0, "rx-bytes": 0, "rx-dropped": 0, "rx-packets": 0, "rx-errs": 0, "tx-bytes": 0, "tx-dropped": 0 } } ] } ``` With this change, the IP address can now be found without errors: ```plain ... windows: WinRM address: 10.0.20.11:5985 windows: WinRM username: vagrant ... ``` --- lib/vagrant-libvirt/driver.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/vagrant-libvirt/driver.rb b/lib/vagrant-libvirt/driver.rb index 42b6e88..f7739d7 100644 --- a/lib/vagrant-libvirt/driver.rb +++ b/lib/vagrant-libvirt/driver.rb @@ -239,6 +239,7 @@ module VagrantPlugins unless addresses.nil? addresses['return'].each do |interface| + next unless interface.key?('hardware-address') next unless domain.mac.downcase == interface['hardware-address'].downcase @logger.debug("Found matching interface: [#{interface['name']}]")