hashicorp/packer

Hyper-V builder assumes that host operating system shares network adapter with VMs

pvandervelde opened this issue · 20 comments

When booting the VM it is possible for Packer to host a webserver from which the VM can download files. The boot command can encode the host IP address by using the following template

preseed/url=http://{{.HTTPIP}}:{{.HTTPPort}}/preseed.cfg

Where HTTPIP and HTTPPort are replaced with the host OS IP address and the suitable port respectively.

This process fails when the host OS does not share the network adapter, i.e. when the host OS has a network adapter for itself and a separate one for the VM networks which is the approach recommended by Microsoft

Software

Packer version: 1.0, but also on the latest version build from #4944
Host platform: Seen in both Windows 10 and on Win 2016

VM response

image

Packer log

==> hyperv-iso: Creating temporary directory...
==> hyperv-iso: Downloading or copying ISO
    hyperv-iso: Downloading or copying: http://codebase.vista.co/artefacts/infrastructure/templates/iso/linux/ubuntu-16.04.1.iso
    hyperv-iso: Download progress: 81%
    hyperv-iso: Download progress: 100%
==> hyperv-iso: Starting HTTP server on port 8457
==> hyperv-iso: Creating switch 'VistaLAN' if required...
==> hyperv-iso:     switch 'VistaLAN' already exists. Will not delete on cleanup...
==> hyperv-iso: Creating virtual machine...
==> hyperv-iso: Enabling Integration Service...
==> hyperv-iso: Setting boot drive to os dvd drive D:/ci/workspace/template-reso---714ad159/build/temp/packer/ubuntu.iso ...
==> hyperv-iso: Mounting os dvd drive D:/ci/workspace/template-reso---714ad159/build/temp/packer/ubuntu.iso ...
==> hyperv-iso: Skipping mounting Integration Services Setup Disk...
==> hyperv-iso: Mounting secondary DVD images...
==> hyperv-iso: Configuring vlan...
==> hyperv-iso: Starting the virtual machine...
==> hyperv-iso: Waiting 5s for boot...
==> hyperv-iso: Host IP for the HyperV machine: False
==> hyperv-iso: Typing the boot command...
==> hyperv-iso: Waiting for SSH to become available...

Note the line that says:

==> hyperv-iso: Host IP for the HyperV machine: False

Could you please provide me the output of the following commands:

Get-VMNetworkAdapter -ManagementOS -SwitchName "VistaLAN" | select deviceid
Get-NetAdapter | select name, deviceid, ifindex, interfacedescription
gwmi win32_networkadapterconfiguration -filter "IPEnabled = 'TRUE'"

From my home PC (where this also happens)

I executed this:

$getVMNetworkAdapterResult = Get-VMNetworkAdapter -ManagementOS -SwitchName "External switch" | select deviceid
$getNetAdapterResult = Get-NetAdapter | select name, deviceid, ifindex, interfacedescription
$wmiResult = gwmi win32_networkadapterconfiguration -filter "IPEnabled = 'TRUE'"

Write-Output ''
Write-Output ''
Write-Output 'Get-VMNetworkAdapter -ManagementOS -SwitchName "External switch" | select deviceid'
$getVMNetworkAdapterResult

Write-Output ''
Write-Output ''
Write-Output 'Get-NetAdapter | select name, deviceid, ifindex, interfacedescription'
$getNetAdapterResult

Write-Output ''
Write-Output ''
Write-Output 'gwmi win32_networkadapterconfiguration -filter "IPEnabled = TRUE"'
$wmiResult

Which results in this:

Get-VMNetworkAdapter -ManagementOS -SwitchName "External switch" | select deviceid


Get-NetAdapter | select name, deviceid, ifindex, interfacedescription

name                         deviceid                               ifIndex interfacedescription                         
----                         --------                               ------- --------------------                         
vEthernet (DockerNAT)        {A224C808-8CB8-4BE1-995C-D2E95279417E}      22 Hyper-V Virtual Ethernet Adapter #2          
vEthernet (HNS Internal NIC) {47515578-DF12-4852-9082-30BEDCC44556}       3 Hyper-V Virtual Ethernet Adapter             
Ethernet-VmClients           {8BEB88C0-4056-47BB-8FC7-94F4DAE74650}       8 Intel(R) Ethernet Connection (2) I218-V      
Ethernet-Host                {7ADFAB95-9AE9-4F69-AF97-DB43FD3A6652}       6 Realtek PCIe GBE Family Controller           
Local Area Connection        {C53CA863-E581-4AD7-81FF-B80A53DFE57D}      16 PPPoP WAN Adapter                            
Ethernet                     {7D7CB049-5A77-4310-AAAE-22CB14245321}       7 Fortinet Virtual Ethernet Adapter (NDIS 6.30)


gwmi win32_networkadapterconfiguration -filter "IPEnabled = TRUE"

The External switch is linked to the Ethernet-VmClients interface

When I'm back at work tomorrow morning I will do the same for the machine there (which does have VistaLAN).

And the outcome of the previously mentioned script on the work machine is:

Get-VMNetworkAdapter -ManagementOS -SwitchName "VistaLAN" | select deviceid


Get-NetAdapter | select name, deviceid, ifindex, interfacedescription

name deviceid                               ifIndex interfacedescription                
---- --------                               ------- --------------------                
Host {387DFE6E-B41A-4417-B0E0-41D50D145263}       3 Microsoft Hyper-V Network Adapter   
VMs  {D9E67C58-81C4-4025-8CDB-B1F2A8CC2C1D}       7 Microsoft Hyper-V Network Adapter #2


gwmi win32_networkadapterconfiguration -filter "IPEnabled = TRUE"

In this case the VistaLAN virtual switch is linked to the VMs interface

Issue what is duplicate #4947 of the current but formally was the first ;-)

DWSR commented

Wanted to confirm that I'm also seeing the same behaviour.

I get similar error behavior on my system. I'm trying to build a Hyper-V provided Debian box, but Hyper-V is not propagating the preseed HTTP server connection into the guest. I can access the HTTP server from the host, but not from the guest.

I tried adding packer.exe through the Windows firewall, but that doesn't seem to be sufficient to fix this error.

Possibly interesting note: For what it's worth, Packer appears to be using the same IP address for both the guest VM and the HTTP server, 192.168.2.12. I'm not sure if this is bad form, or if this usually works. Anyway, thought that might be a contributing factor.

packer configuration:

{
  "builders": [
    {
      "type": "hyperv-iso",
      "vm_name": "debian",
      "iso_url": "http://cdimage.debian.org/cdimage/release/9.2.1/amd64/iso-cd/debian-9.2.1-amd64-netinst.iso",
      "iso_checksum_type": "sha512",
      "iso_checksum": "ebfe25dc593967e39349b205480b0ec0103ef4a0468c602f4857e13d06d407bfe876162399e0e8d4dea5675953dc37ab585316f307ccf9f4440124b4f719df04",
      "ssh_username": "vagrant",
      "ssh_password": "vagrant",
      "ssh_timeout": "1800s",
      "disk_size": 8000,
      "ram_size": 1024,
      "http_directory": "http",
      "boot_command": [
        "<esc><wait>",
        "install ",
        "preseed/url=http://{{.HTTPIP}}:{{.HTTPPort}}/preseed.cfg ",
        "locale=en_US ",
        "kbd-chooser/method=us ",
        "keyboard-configuration/xkb-keymap=us ",
        "netcfg/get_hostname={{.Name}} ",
        "netcfg/get_domain=vagrantup.com ",
        "debconf/frontend=noninteractive ",
        "fb=false ",
        "<enter><wait>"
      ],
      "shutdown_command": "sudo halt -p"
    }
  ],
  "post-processors": [
    {
      "type": "vagrant",
      "output": "debian-{{.Provider}}.box",
      "compression_level": "9"
    }
  ]
}

So... no solution for the issue yet?
My Hyper-V servers are also configured to use dedicated network adapters for host OS and separate adapters for Hyper-V External VSwitches and packer fails with the error:

==> hyperv-iso: Skipping mounting Integration Services Setup Disk...
==> hyperv-iso: Mounting secondary DVD images...
==> hyperv-iso: Configuring vlan...
==> hyperv-iso: Starting the virtual machine...
==> hyperv-iso: Error getting host adapter ip address: PowerShell error: Get-VMNetworkAdapter : No network adapter is found with the given input.
==> hyperv-iso: At C:\Users\...\AppData\Local\Temp\ps345316363.ps1:4 char:18
==> hyperv-iso: + $HostVMAdapter = Get-VMNetworkAdapter -ManagementOS -SwitchName $switchName
==> hyperv-iso:     + CategoryInfo          : ObjectNotFound: (VmInterconnectSwitch:String) [Get-VMNetworkAdapter], VirtualizationOperationFailedException
==> hyperv-iso:     + FullyQualifiedErrorId : ObjectNotFound,Microsoft.HyperV.PowerShell.Commands.GetVMNetworkAdapterCommand

The hyper-V builder is a community-maintained plugin; we'll gladly review any PR submitted to fix this.

@SwampDragons - It's extremely hard when you have no clue about Go ;)
Just asking - I've hit this problem long time ago. Can we, for example, add extra variable for, I don't know, interface name to get IPs from?
Right now, for what I could guess it tries to interact with 'ManagementOS' part of VmNetworkAdapter. When it's not present, it defaults to False.
I think we can:

  • when it's false on non-ip looking, try to get primary interface's IP?
  • when we have variable, use override and get IP from variable defined network-adapter?
  • replace 'false' with '0.0.0.0'?

I pulled down the current nightly as I encountered this issue myself, and wanted to test the recently merged fix.

The releases page indicates the release was produced from 65d6677, which seems to have the fix included.

However, in my environment it seems the problem persists:

Get-ChildItem ENV:PACKER*

Name                           Value
----                           -----
PACKER_BUILD_NAME              HyperV-Windows10
PACKER_BUILDER_TYPE            hyperv-vmcx
PACKER_HTTP_ADDR               False:8684
PACKER_HTTP_IP                 False
PACKER_HTTP_PORT               8684

I'm not sure what's unique about my configuration that might cause this issue. Can (or should) this issue be re-opened?

Bummer. @Rychard can you share your debug logs and repro case?

Here you go @SwampDragons

https://gist.github.com/Rychard/715f9b4a896378ce61adc5287dd97b76

It's far from a Minimal, Complete, and Verifiable example, but I tried to capture as many relevant details about my configuration as I could think of.

The build in the gist is a continuation of a base Windows installation (step 1), followed by installing Windows updates (step 2). There's nothing magical about those steps, in fact they were obtained by modifying these builds.

Here's a much smaller repro using alpine linux. I started with this template, but since HTTPIP resolves to False, that template fails early on in the boot_command since it can't obtain the answers file from the http_directory.

Consequently, I decided to truncate everything else in that template and modified it to simply type the variables into the shell. I did have to set "headless": "false" in order to see them (since SSH hasn't even been configured at this point), so I've included a screenshot instead.

packer_windows_amd64.exe build repro.json
// repro.json
{
    "builders": [
        {
            "type": "hyperv-iso",
            "iso_url": "http://dl-cdn.alpinelinux.org/alpine/v3.6/releases/x86_64/alpine-virt-3.6.2-x86_64.iso",
            "iso_checksum": "92c80e151143da155fb99611ed8f0f3672fba4de228a85eb5f53bcb261bf4b0a",
            "iso_checksum_type": "sha256",
            "disk_size": "512",
            "skip_compaction": "true",
            "communicator": "ssh",
            "ssh_username": "root",
            "ssh_password": "alpine",
            "http_directory": "./office/",
            "boot_wait": "5s",
            "headless": "false",
            "boot_command": [
                "root<enter><wait>",
                "echo '{{ .HTTPIP }}:{{ .HTTPPort }}'<enter>"
            ],
            "shutdown_command": "poweroff",
            "generation": 1,
            "enable_secure_boot": false
        }
    ]
}

image

@SwampDragons I need to confirm - packer-nightly produces same result in my config.

Thanks.

Hi @SwampDragons - 1.4.3 version doesn't solve the issue.
image

Hi @SwampDragons - I was able te replicate it and using extra fast course 'learn Go' my dev version of packer seems to work with finding ip in case when management interface is not part of VirtualSwitch.
As my knowledge of Go is minimal, if someone could review it - great. I'll try to do PR tomorrow.

image

image

Wonderful! I look forward to reviewing your PR.

It's here: #8017

I'm going to lock this issue because it has been closed for 30 days ⏳. This helps our maintainers find and focus on the active issues.

If you have found a problem that seems similar to this, please open a new issue and complete the issue template so we can capture all the details necessary to investigate further.