hashicorp / packer

Packer is a tool for creating identical machine images for multiple platforms from a single source configuration.
http://www.packer.io
Other
15.05k stars 3.32k forks source link

Unable to template vboxmanage field with array values #8848

Open mtarral opened 4 years ago

mtarral commented 4 years ago

When filing a bug, please include the following headings if possible. Any example text in this template can be deleted.

Overview of the Issue

Templating the vboxmanage field of the virtualbox-iso builder is not possible with array values

I would like to template the field vboxmanage using a varfile: windows.json

"vboxmanage": "{{ user `vboxmanage_cmds` }}"

win10.json (varfile)

"vboxmanage_cmds": "modifyvm win10 --acpi on,modifyvm win10 --clipboard disabled"

But this fails, as Packer is interpreting modifyvm win10 --acpi on,modifyvm win10 --clipboard disabled as a single command.

I've also tried:

"vboxmanage": [
    "{{ user `vboxmanage_cmds` }}"
]

But it doesn't work either.

Ideally I would like to following behavior: Be able to write a set of VBoxManage commands common to my windows templates, completed with a variable for specific tuning from the varfile

windows.json

"vboxmanage": [
    ["modifyvm", "{{.Name}}", "--acpi", "on"],
    "{{ user `vboxmanage_cmds` }}"
]

win10.json (varfile)

"vboxmanage_cmds": [
    ["modifyvm", "{{.Name}}, "--clipboard", "disabled",
    etc...
]

As I have to write 10-20 lines of VBoxManage commands, I don't want to have them on a single string, separated by ,, it would be unmaintanable.

Reproduction Steps

git clone https://github.com/Wenzel/packer-templates -b bug_vboxmanage_template packer build -only virtualbox-iso -var-file win10.json windows.json

Packer version

From 1.5.4

Simplified Packer Buildfile

windows.json (template) ~~~JSON { "_comment": "Build with `packer build windows.json`", "builders": [ { "type": "qemu", "accelerator": "kvm", "vm_name": "{{user `vm_name`}}.qcow2", "format": "qcow2", "cpus": "{{ user `cpus` }}", "memory": "{{ user `memory` }}", "iso_url": "{{user `iso_url`}}", "iso_checksum_type": "{{user `iso_checksum_type`}}", "iso_checksum": "{{user `iso_checksum`}}", "headless": "{{user `headless`}}", "skip_compaction": false, "disk_compression": true, "boot_wait": "2m", "communicator": "winrm", "winrm_username": "{{user `winrm_username`}}", "winrm_password": "{{user `winrm_password`}}", "winrm_timeout": "{{user `winrm_timeout`}}", "shutdown_command": "shutdown /s /t 10 /f /d p:4:1 /c \"Packer Shutdown\"", "disk_size": "{{user `disk_size`}}", "disk_interface": "ide", "vnc_bind_address": "0.0.0.0", "net_device": "rtl8139", "http_directory": "http", "http_port_min": 8500, "http_port_max": 8500, "floppy_files": [ "{{user `autounattend`}}", "scripts/wget-win32-static.zip", "scripts/extract_wget_zip.vbs", "scripts/setup_winrm.bat", "scripts/fixnetwork.ps1", "scripts/setup_winrm_public.bat" ] }, { "type": "virtualbox-iso", "guest_os_type": "{{ user `guest_os_type` }}", "vm_name": "{{ user `vm_name` }}", "format": "ova", "cpus": "{{ user `cpus` }}", "memory": "{{ user `memory` }}", "iso_url": "{{user `iso_url`}}", "iso_checksum_type": "{{user `iso_checksum_type`}}", "iso_checksum": "{{user `iso_checksum`}}", "headless": "{{ user `headless` }}", "boot_wait": "2m", "communicator": "winrm", "winrm_username": "{{ user `winrm_username` }}", "winrm_password": "{{ user `winrm_password` }}", "winrm_timeout": "8h", "shutdown_command": "shutdown /s /t 10 /f /d p:4:1 /c \"Packer Shutdown\"", "disk_size": 40000, "hard_drive_interface": "ide", "http_directory": "http", "http_port_min": 8500, "http_port_max": 8500, "vrdp_bind_address": "0.0.0.0", "floppy_files": [ "{{user `autounattend`}}", "scripts/wget-win32-static.zip", "scripts/extract_wget_zip.vbs", "scripts/setup_winrm.bat", "scripts/fixnetwork.ps1", "scripts/setup_winrm_public.bat" ], "vboxmanage": [ ["modifyvm", "win10", "--acpi", "on"], "{{ user `vboxmanage_cmds` }}" ] } ], "variables": { "cpus": "1", "disk_size": "65536", "headless": "true", "memory": "2048", "winrm_password": "vagrant", "winrm_username": "vagrant", "winrm_timeout": "8h", "vm_name": "win7x64", "autounattend": "answer_files/7/Autounattend.xml" } } ~~~
win10.json (varfile) ~~~JSON { "vm_name": "win10", "cpus": "1", "memory": "2048", "disk_size": "65536", "iso_url": "http://download.microsoft.com/download/C/3/9/C399EEA8-135D-4207-92C9-6AAB3259F6EF/10240.16384.150709-1700.TH1_CLIENTENTERPRISEEVAL_OEMRET_X64FRE_EN-US.ISO", "iso_checksum_type": "sha1", "iso_checksum": "56ab095075be28a90bc0b510835280975c6bb2ce", "autounattend": "./answer_files/10/Autounattend.xml", "vboxmanage_cmds": "modifyvm win10 --acpi on" } ~~~

Operating system and Environment details

OS: Debian Buster

Log Fragments and crash.log files

Relevant log file information:

2020/03/06 10:40:57 packer_1.5.4 plugin: Executing VBoxManage: []string{"modifyvm", "win10", "--natpf1", "packercomm,tcp,127.0.0.1,2477,,5985"}
==> virtualbox-iso: Creating forwarded port mapping for communicator (SSH, WinRM, etc) (host port 2477)
2020/03/06 10:40:57 packer_1.5.4 plugin: stdout:
2020/03/06 10:40:57 packer_1.5.4 plugin: stderr:
==> virtualbox-iso: Executing custom VBoxManage commands...
    virtualbox-iso: Executing: modifyvm win10 --acpi on
2020/03/06 10:40:57 packer_1.5.4 plugin: Executing VBoxManage: []string{"modifyvm", "win10", "--acpi", "on"}
2020/03/06 10:40:57 packer_1.5.4 plugin: stdout:
2020/03/06 10:40:57 packer_1.5.4 plugin: stderr:
    virtualbox-iso: Executing: modifyvm win10 --acpi on
2020/03/06 10:40:57 packer_1.5.4 plugin: Executing VBoxManage: []string{"modifyvm win10 --acpi on"}
2020/03/06 10:40:57 packer_1.5.4 plugin: stdout:
2020/03/06 10:40:57 packer_1.5.4 plugin: stderr: Oracle VM VirtualBox Command Line Management Interface Version 6.0.8
2020/03/06 10:40:57 packer_1.5.4 plugin: (C) 2005-2020 Oracle Corporation
2020/03/06 10:40:57 packer_1.5.4 plugin: All rights reserved.
2020/03/06 10:40:57 packer_1.5.4 plugin: 
2020/03/06 10:40:57 packer_1.5.4 plugin: Usage:
2020/03/06 10:40:57 packer_1.5.4 plugin: 
2020/03/06 10:40:57 packer_1.5.4 plugin:   VBoxManage [<general option>] <command>

You can see the difference between the 2 commands executed:

Executing VBoxManage: []string{"modifyvm", "win10", "--acpi", "on"}

vs

Executing VBoxManage: []string{"modifyvm win10 --acpi on"}

Thanks !

nywilken commented 4 years ago

Good to know, thanks! We’ll take a look when we get a chance.

SwampDragons commented 4 years ago

I think this has to do with the way in which we interpolate values from json into golang maps. It's not an area we change very often, and has some rough edges. Since this is an edge case (there really aren't a lot of situations where users come up against nested arrays) I'm not sure when we will have a chance to do the work to investigate this and change it in a way we are certain won't have negative repercussions for other users.

In the meantime, I'd suggest that you try out using HCL2 packer templates instead (see https://packer.io/guides/hcl/ for docs). We're still getting them up to speed, but they support data structures much more natively than the json templates do.