From 4fd76f36ddf5036ae7a96e57a5264f9a53634226 Mon Sep 17 00:00:00 2001 From: Andreas Botzner Date: Mon, 27 Jul 2020 11:08:54 +0200 Subject: [PATCH] Allows for the mounting of ISOs when a Proxmox VM s created. Same as in PR 9055 but working Fixed check-lint errors Fixed bus_number check Fixed check-genereate error Revert "Fixed bus_number check" This reverts commit ac8dc157056708d4f87215cca120cc4e0ff49146. fmt Naming Fixed hcl2 autogenerated code issue fmt less than is not greater than --- builder/proxmox/config.go | 34 +++- builder/proxmox/config.hcl2spec.go | 219 ++++++++++++++---------- builder/proxmox/step_start_vm.go | 13 ++ website/pages/docs/builders/proxmox.mdx | 23 ++- 4 files changed, 192 insertions(+), 97 deletions(-) diff --git a/builder/proxmox/config.go b/builder/proxmox/config.go index 3610379c3ce..9f02aed9f13 100644 --- a/builder/proxmox/config.go +++ b/builder/proxmox/config.go @@ -1,4 +1,4 @@ -//go:generate mapstructure-to-hcl2 -type Config,nicConfig,diskConfig,vgaConfig +//go:generate mapstructure-to-hcl2 -type Config,nicConfig,diskConfig,vgaConfig,storageConfig package proxmox @@ -64,6 +64,8 @@ type Config struct { shouldUploadISO bool + AdditionalISOFiles []storageConfig `mapstructure:"additional_iso_files"` + ctx interpolate.Context } @@ -87,6 +89,11 @@ type vgaConfig struct { Type string `mapstructure:"type"` Memory int `mapstructure:"memory"` } +type storageConfig struct { + Device string `mapstructure:"device"` + BusNumber int `mapstructure:"bus_number"` + Filename string `mapstructure:"filename"` +} func (c *Config) Prepare(raws ...interface{}) ([]string, error) { // Agent defaults to true @@ -183,6 +190,31 @@ func (c *Config) Prepare(raws ...interface{}) ([]string, error) { errs = packer.MultiErrorAppend(errs, fmt.Errorf("disk format must be specified for pool type %q", c.Disks[idx].StoragePoolType)) } } + for idx := range c.AdditionalISOFiles { + if c.AdditionalISOFiles[idx].Device == "" { + log.Printf("AdditionalISOFile %d Device not set, using default 'ide'", idx) + c.AdditionalISOFiles[idx].Device = "ide" + } + if !contains([]string{"ide", "sata", "scsi"}, c.AdditionalISOFiles[idx].Device) { + errs = packer.MultiErrorAppend(errs, fmt.Errorf("%q is not a valid AdditionalISOFile Device", c.AdditionalISOFiles[idx])) + } + if c.AdditionalISOFiles[idx].BusNumber == 0 { + log.Printf("AdditionalISOFile %d number not set, using default: '3'", idx) + c.AdditionalISOFiles[idx].BusNumber = 3 + } + if c.AdditionalISOFiles[idx].Device == "ide" && c.AdditionalISOFiles[idx].BusNumber == 2 { + errs = packer.MultiErrorAppend(errs, fmt.Errorf("IDE bus 2 is used by boot ISO")) + } + if c.AdditionalISOFiles[idx].Device == "ide" && c.AdditionalISOFiles[idx].BusNumber > 3 { + errs = packer.MultiErrorAppend(errs, fmt.Errorf("IDE bus number can't be higher than 3")) + } + if c.AdditionalISOFiles[idx].Device == "sata" && c.AdditionalISOFiles[idx].BusNumber > 5 { + errs = packer.MultiErrorAppend(errs, fmt.Errorf("SATA bus number can't be higher than 5")) + } + if c.AdditionalISOFiles[idx].Device == "scsi" && c.AdditionalISOFiles[idx].BusNumber > 30 { + errs = packer.MultiErrorAppend(errs, fmt.Errorf("SCSI bus number can't be higher than 30")) + } + } if c.SCSIController == "" { log.Printf("SCSI controller not set, using default 'lsi'") c.SCSIController = "lsi" diff --git a/builder/proxmox/config.hcl2spec.go b/builder/proxmox/config.hcl2spec.go index f8d868f85ec..d909fb3704d 100644 --- a/builder/proxmox/config.hcl2spec.go +++ b/builder/proxmox/config.hcl2spec.go @@ -1,4 +1,4 @@ -// Code generated by "mapstructure-to-hcl2 -type Config,nicConfig,diskConfig,vgaConfig"; DO NOT EDIT. +// Code generated by "mapstructure-to-hcl2 -type Config,nicConfig,diskConfig,vgaConfig,storageConfig"; DO NOT EDIT. package proxmox import ( @@ -9,100 +9,101 @@ import ( // FlatConfig is an auto-generated flat version of Config. // Where the contents of a field with a `mapstructure:,squash` tag are bubbled up. type FlatConfig struct { - PackerBuildName *string `mapstructure:"packer_build_name" cty:"packer_build_name" hcl:"packer_build_name"` - PackerBuilderType *string `mapstructure:"packer_builder_type" cty:"packer_builder_type" hcl:"packer_builder_type"` - PackerDebug *bool `mapstructure:"packer_debug" cty:"packer_debug" hcl:"packer_debug"` - PackerForce *bool `mapstructure:"packer_force" cty:"packer_force" hcl:"packer_force"` - PackerOnError *string `mapstructure:"packer_on_error" cty:"packer_on_error" hcl:"packer_on_error"` - PackerUserVars map[string]string `mapstructure:"packer_user_variables" cty:"packer_user_variables" hcl:"packer_user_variables"` - PackerSensitiveVars []string `mapstructure:"packer_sensitive_variables" cty:"packer_sensitive_variables" hcl:"packer_sensitive_variables"` - HTTPDir *string `mapstructure:"http_directory" cty:"http_directory" hcl:"http_directory"` - HTTPPortMin *int `mapstructure:"http_port_min" cty:"http_port_min" hcl:"http_port_min"` - HTTPPortMax *int `mapstructure:"http_port_max" cty:"http_port_max" hcl:"http_port_max"` - HTTPAddress *string `mapstructure:"http_bind_address" cty:"http_bind_address" hcl:"http_bind_address"` - ISOChecksum *string `mapstructure:"iso_checksum" required:"true" cty:"iso_checksum" hcl:"iso_checksum"` - RawSingleISOUrl *string `mapstructure:"iso_url" required:"true" cty:"iso_url" hcl:"iso_url"` - ISOUrls []string `mapstructure:"iso_urls" cty:"iso_urls" hcl:"iso_urls"` - TargetPath *string `mapstructure:"iso_target_path" cty:"iso_target_path" hcl:"iso_target_path"` - TargetExtension *string `mapstructure:"iso_target_extension" cty:"iso_target_extension" hcl:"iso_target_extension"` - BootGroupInterval *string `mapstructure:"boot_keygroup_interval" cty:"boot_keygroup_interval" hcl:"boot_keygroup_interval"` - BootWait *string `mapstructure:"boot_wait" cty:"boot_wait" hcl:"boot_wait"` - BootCommand []string `mapstructure:"boot_command" cty:"boot_command" hcl:"boot_command"` - BootKeyInterval *string `mapstructure:"boot_key_interval" cty:"boot_key_interval" hcl:"boot_key_interval"` - Type *string `mapstructure:"communicator" cty:"communicator" hcl:"communicator"` - PauseBeforeConnect *string `mapstructure:"pause_before_connecting" cty:"pause_before_connecting" hcl:"pause_before_connecting"` - SSHHost *string `mapstructure:"ssh_host" cty:"ssh_host" hcl:"ssh_host"` - SSHPort *int `mapstructure:"ssh_port" cty:"ssh_port" hcl:"ssh_port"` - SSHUsername *string `mapstructure:"ssh_username" cty:"ssh_username" hcl:"ssh_username"` - SSHPassword *string `mapstructure:"ssh_password" cty:"ssh_password" hcl:"ssh_password"` - SSHKeyPairName *string `mapstructure:"ssh_keypair_name" undocumented:"true" cty:"ssh_keypair_name" hcl:"ssh_keypair_name"` - SSHTemporaryKeyPairName *string `mapstructure:"temporary_key_pair_name" undocumented:"true" cty:"temporary_key_pair_name" hcl:"temporary_key_pair_name"` - SSHCiphers []string `mapstructure:"ssh_ciphers" cty:"ssh_ciphers" hcl:"ssh_ciphers"` - SSHClearAuthorizedKeys *bool `mapstructure:"ssh_clear_authorized_keys" cty:"ssh_clear_authorized_keys" hcl:"ssh_clear_authorized_keys"` - SSHKEXAlgos []string `mapstructure:"ssh_key_exchange_algorithms" cty:"ssh_key_exchange_algorithms" hcl:"ssh_key_exchange_algorithms"` - SSHPrivateKeyFile *string `mapstructure:"ssh_private_key_file" undocumented:"true" cty:"ssh_private_key_file" hcl:"ssh_private_key_file"` - SSHCertificateFile *string `mapstructure:"ssh_certificate_file" cty:"ssh_certificate_file" hcl:"ssh_certificate_file"` - SSHPty *bool `mapstructure:"ssh_pty" cty:"ssh_pty" hcl:"ssh_pty"` - SSHTimeout *string `mapstructure:"ssh_timeout" cty:"ssh_timeout" hcl:"ssh_timeout"` - SSHWaitTimeout *string `mapstructure:"ssh_wait_timeout" undocumented:"true" cty:"ssh_wait_timeout" hcl:"ssh_wait_timeout"` - SSHAgentAuth *bool `mapstructure:"ssh_agent_auth" undocumented:"true" cty:"ssh_agent_auth" hcl:"ssh_agent_auth"` - SSHDisableAgentForwarding *bool `mapstructure:"ssh_disable_agent_forwarding" cty:"ssh_disable_agent_forwarding" hcl:"ssh_disable_agent_forwarding"` - SSHHandshakeAttempts *int `mapstructure:"ssh_handshake_attempts" cty:"ssh_handshake_attempts" hcl:"ssh_handshake_attempts"` - SSHBastionHost *string `mapstructure:"ssh_bastion_host" cty:"ssh_bastion_host" hcl:"ssh_bastion_host"` - SSHBastionPort *int `mapstructure:"ssh_bastion_port" cty:"ssh_bastion_port" hcl:"ssh_bastion_port"` - SSHBastionAgentAuth *bool `mapstructure:"ssh_bastion_agent_auth" cty:"ssh_bastion_agent_auth" hcl:"ssh_bastion_agent_auth"` - SSHBastionUsername *string `mapstructure:"ssh_bastion_username" cty:"ssh_bastion_username" hcl:"ssh_bastion_username"` - SSHBastionPassword *string `mapstructure:"ssh_bastion_password" cty:"ssh_bastion_password" hcl:"ssh_bastion_password"` - SSHBastionInteractive *bool `mapstructure:"ssh_bastion_interactive" cty:"ssh_bastion_interactive" hcl:"ssh_bastion_interactive"` - SSHBastionPrivateKeyFile *string `mapstructure:"ssh_bastion_private_key_file" cty:"ssh_bastion_private_key_file" hcl:"ssh_bastion_private_key_file"` - SSHBastionCertificateFile *string `mapstructure:"ssh_bastion_certificate_file" cty:"ssh_bastion_certificate_file" hcl:"ssh_bastion_certificate_file"` - SSHFileTransferMethod *string `mapstructure:"ssh_file_transfer_method" cty:"ssh_file_transfer_method" hcl:"ssh_file_transfer_method"` - SSHProxyHost *string `mapstructure:"ssh_proxy_host" cty:"ssh_proxy_host" hcl:"ssh_proxy_host"` - SSHProxyPort *int `mapstructure:"ssh_proxy_port" cty:"ssh_proxy_port" hcl:"ssh_proxy_port"` - SSHProxyUsername *string `mapstructure:"ssh_proxy_username" cty:"ssh_proxy_username" hcl:"ssh_proxy_username"` - SSHProxyPassword *string `mapstructure:"ssh_proxy_password" cty:"ssh_proxy_password" hcl:"ssh_proxy_password"` - SSHKeepAliveInterval *string `mapstructure:"ssh_keep_alive_interval" cty:"ssh_keep_alive_interval" hcl:"ssh_keep_alive_interval"` - SSHReadWriteTimeout *string `mapstructure:"ssh_read_write_timeout" cty:"ssh_read_write_timeout" hcl:"ssh_read_write_timeout"` - SSHRemoteTunnels []string `mapstructure:"ssh_remote_tunnels" cty:"ssh_remote_tunnels" hcl:"ssh_remote_tunnels"` - SSHLocalTunnels []string `mapstructure:"ssh_local_tunnels" cty:"ssh_local_tunnels" hcl:"ssh_local_tunnels"` - SSHPublicKey []byte `mapstructure:"ssh_public_key" undocumented:"true" cty:"ssh_public_key" hcl:"ssh_public_key"` - SSHPrivateKey []byte `mapstructure:"ssh_private_key" undocumented:"true" cty:"ssh_private_key" hcl:"ssh_private_key"` - WinRMUser *string `mapstructure:"winrm_username" cty:"winrm_username" hcl:"winrm_username"` - WinRMPassword *string `mapstructure:"winrm_password" cty:"winrm_password" hcl:"winrm_password"` - WinRMHost *string `mapstructure:"winrm_host" cty:"winrm_host" hcl:"winrm_host"` - WinRMNoProxy *bool `mapstructure:"winrm_no_proxy" cty:"winrm_no_proxy" hcl:"winrm_no_proxy"` - WinRMPort *int `mapstructure:"winrm_port" cty:"winrm_port" hcl:"winrm_port"` - WinRMTimeout *string `mapstructure:"winrm_timeout" cty:"winrm_timeout" hcl:"winrm_timeout"` - WinRMUseSSL *bool `mapstructure:"winrm_use_ssl" cty:"winrm_use_ssl" hcl:"winrm_use_ssl"` - WinRMInsecure *bool `mapstructure:"winrm_insecure" cty:"winrm_insecure" hcl:"winrm_insecure"` - WinRMUseNTLM *bool `mapstructure:"winrm_use_ntlm" cty:"winrm_use_ntlm" hcl:"winrm_use_ntlm"` - ProxmoxURLRaw *string `mapstructure:"proxmox_url" cty:"proxmox_url" hcl:"proxmox_url"` - SkipCertValidation *bool `mapstructure:"insecure_skip_tls_verify" cty:"insecure_skip_tls_verify" hcl:"insecure_skip_tls_verify"` - Username *string `mapstructure:"username" cty:"username" hcl:"username"` - Password *string `mapstructure:"password" cty:"password" hcl:"password"` - Node *string `mapstructure:"node" cty:"node" hcl:"node"` - Pool *string `mapstructure:"pool" cty:"pool" hcl:"pool"` - VMName *string `mapstructure:"vm_name" cty:"vm_name" hcl:"vm_name"` - VMID *int `mapstructure:"vm_id" cty:"vm_id" hcl:"vm_id"` - Memory *int `mapstructure:"memory" cty:"memory" hcl:"memory"` - Cores *int `mapstructure:"cores" cty:"cores" hcl:"cores"` - CPUType *string `mapstructure:"cpu_type" cty:"cpu_type" hcl:"cpu_type"` - Sockets *int `mapstructure:"sockets" cty:"sockets" hcl:"sockets"` - OS *string `mapstructure:"os" cty:"os" hcl:"os"` - VGA *FlatvgaConfig `mapstructure:"vga" cty:"vga" hcl:"vga"` - NICs []FlatnicConfig `mapstructure:"network_adapters" cty:"network_adapters" hcl:"network_adapters"` - Disks []FlatdiskConfig `mapstructure:"disks" cty:"disks" hcl:"disks"` - ISOFile *string `mapstructure:"iso_file" cty:"iso_file" hcl:"iso_file"` - ISOStoragePool *string `mapstructure:"iso_storage_pool" cty:"iso_storage_pool" hcl:"iso_storage_pool"` - Agent *bool `mapstructure:"qemu_agent" cty:"qemu_agent" hcl:"qemu_agent"` - SCSIController *string `mapstructure:"scsi_controller" cty:"scsi_controller" hcl:"scsi_controller"` - Onboot *bool `mapstructure:"onboot" cty:"onboot" hcl:"onboot"` - DisableKVM *bool `mapstructure:"disable_kvm" cty:"disable_kvm" hcl:"disable_kvm"` - TemplateName *string `mapstructure:"template_name" cty:"template_name" hcl:"template_name"` - TemplateDescription *string `mapstructure:"template_description" cty:"template_description" hcl:"template_description"` - UnmountISO *bool `mapstructure:"unmount_iso" cty:"unmount_iso" hcl:"unmount_iso"` - CloudInit *bool `mapstructure:"cloud_init" cty:"cloud_init" hcl:"cloud_init"` - CloudInitStoragePool *string `mapstructure:"cloud_init_storage_pool" cty:"cloud_init_storage_pool" hcl:"cloud_init_storage_pool"` + PackerBuildName *string `mapstructure:"packer_build_name" cty:"packer_build_name" hcl:"packer_build_name"` + PackerBuilderType *string `mapstructure:"packer_builder_type" cty:"packer_builder_type" hcl:"packer_builder_type"` + PackerDebug *bool `mapstructure:"packer_debug" cty:"packer_debug" hcl:"packer_debug"` + PackerForce *bool `mapstructure:"packer_force" cty:"packer_force" hcl:"packer_force"` + PackerOnError *string `mapstructure:"packer_on_error" cty:"packer_on_error" hcl:"packer_on_error"` + PackerUserVars map[string]string `mapstructure:"packer_user_variables" cty:"packer_user_variables" hcl:"packer_user_variables"` + PackerSensitiveVars []string `mapstructure:"packer_sensitive_variables" cty:"packer_sensitive_variables" hcl:"packer_sensitive_variables"` + HTTPDir *string `mapstructure:"http_directory" cty:"http_directory" hcl:"http_directory"` + HTTPPortMin *int `mapstructure:"http_port_min" cty:"http_port_min" hcl:"http_port_min"` + HTTPPortMax *int `mapstructure:"http_port_max" cty:"http_port_max" hcl:"http_port_max"` + HTTPAddress *string `mapstructure:"http_bind_address" cty:"http_bind_address" hcl:"http_bind_address"` + ISOChecksum *string `mapstructure:"iso_checksum" required:"true" cty:"iso_checksum" hcl:"iso_checksum"` + RawSingleISOUrl *string `mapstructure:"iso_url" required:"true" cty:"iso_url" hcl:"iso_url"` + ISOUrls []string `mapstructure:"iso_urls" cty:"iso_urls" hcl:"iso_urls"` + TargetPath *string `mapstructure:"iso_target_path" cty:"iso_target_path" hcl:"iso_target_path"` + TargetExtension *string `mapstructure:"iso_target_extension" cty:"iso_target_extension" hcl:"iso_target_extension"` + BootGroupInterval *string `mapstructure:"boot_keygroup_interval" cty:"boot_keygroup_interval" hcl:"boot_keygroup_interval"` + BootWait *string `mapstructure:"boot_wait" cty:"boot_wait" hcl:"boot_wait"` + BootCommand []string `mapstructure:"boot_command" cty:"boot_command" hcl:"boot_command"` + BootKeyInterval *string `mapstructure:"boot_key_interval" cty:"boot_key_interval" hcl:"boot_key_interval"` + Type *string `mapstructure:"communicator" cty:"communicator" hcl:"communicator"` + PauseBeforeConnect *string `mapstructure:"pause_before_connecting" cty:"pause_before_connecting" hcl:"pause_before_connecting"` + SSHHost *string `mapstructure:"ssh_host" cty:"ssh_host" hcl:"ssh_host"` + SSHPort *int `mapstructure:"ssh_port" cty:"ssh_port" hcl:"ssh_port"` + SSHUsername *string `mapstructure:"ssh_username" cty:"ssh_username" hcl:"ssh_username"` + SSHPassword *string `mapstructure:"ssh_password" cty:"ssh_password" hcl:"ssh_password"` + SSHKeyPairName *string `mapstructure:"ssh_keypair_name" undocumented:"true" cty:"ssh_keypair_name" hcl:"ssh_keypair_name"` + SSHTemporaryKeyPairName *string `mapstructure:"temporary_key_pair_name" undocumented:"true" cty:"temporary_key_pair_name" hcl:"temporary_key_pair_name"` + SSHCiphers []string `mapstructure:"ssh_ciphers" cty:"ssh_ciphers" hcl:"ssh_ciphers"` + SSHClearAuthorizedKeys *bool `mapstructure:"ssh_clear_authorized_keys" cty:"ssh_clear_authorized_keys" hcl:"ssh_clear_authorized_keys"` + SSHKEXAlgos []string `mapstructure:"ssh_key_exchange_algorithms" cty:"ssh_key_exchange_algorithms" hcl:"ssh_key_exchange_algorithms"` + SSHPrivateKeyFile *string `mapstructure:"ssh_private_key_file" undocumented:"true" cty:"ssh_private_key_file" hcl:"ssh_private_key_file"` + SSHCertificateFile *string `mapstructure:"ssh_certificate_file" cty:"ssh_certificate_file" hcl:"ssh_certificate_file"` + SSHPty *bool `mapstructure:"ssh_pty" cty:"ssh_pty" hcl:"ssh_pty"` + SSHTimeout *string `mapstructure:"ssh_timeout" cty:"ssh_timeout" hcl:"ssh_timeout"` + SSHWaitTimeout *string `mapstructure:"ssh_wait_timeout" undocumented:"true" cty:"ssh_wait_timeout" hcl:"ssh_wait_timeout"` + SSHAgentAuth *bool `mapstructure:"ssh_agent_auth" undocumented:"true" cty:"ssh_agent_auth" hcl:"ssh_agent_auth"` + SSHDisableAgentForwarding *bool `mapstructure:"ssh_disable_agent_forwarding" cty:"ssh_disable_agent_forwarding" hcl:"ssh_disable_agent_forwarding"` + SSHHandshakeAttempts *int `mapstructure:"ssh_handshake_attempts" cty:"ssh_handshake_attempts" hcl:"ssh_handshake_attempts"` + SSHBastionHost *string `mapstructure:"ssh_bastion_host" cty:"ssh_bastion_host" hcl:"ssh_bastion_host"` + SSHBastionPort *int `mapstructure:"ssh_bastion_port" cty:"ssh_bastion_port" hcl:"ssh_bastion_port"` + SSHBastionAgentAuth *bool `mapstructure:"ssh_bastion_agent_auth" cty:"ssh_bastion_agent_auth" hcl:"ssh_bastion_agent_auth"` + SSHBastionUsername *string `mapstructure:"ssh_bastion_username" cty:"ssh_bastion_username" hcl:"ssh_bastion_username"` + SSHBastionPassword *string `mapstructure:"ssh_bastion_password" cty:"ssh_bastion_password" hcl:"ssh_bastion_password"` + SSHBastionInteractive *bool `mapstructure:"ssh_bastion_interactive" cty:"ssh_bastion_interactive" hcl:"ssh_bastion_interactive"` + SSHBastionPrivateKeyFile *string `mapstructure:"ssh_bastion_private_key_file" cty:"ssh_bastion_private_key_file" hcl:"ssh_bastion_private_key_file"` + SSHBastionCertificateFile *string `mapstructure:"ssh_bastion_certificate_file" cty:"ssh_bastion_certificate_file" hcl:"ssh_bastion_certificate_file"` + SSHFileTransferMethod *string `mapstructure:"ssh_file_transfer_method" cty:"ssh_file_transfer_method" hcl:"ssh_file_transfer_method"` + SSHProxyHost *string `mapstructure:"ssh_proxy_host" cty:"ssh_proxy_host" hcl:"ssh_proxy_host"` + SSHProxyPort *int `mapstructure:"ssh_proxy_port" cty:"ssh_proxy_port" hcl:"ssh_proxy_port"` + SSHProxyUsername *string `mapstructure:"ssh_proxy_username" cty:"ssh_proxy_username" hcl:"ssh_proxy_username"` + SSHProxyPassword *string `mapstructure:"ssh_proxy_password" cty:"ssh_proxy_password" hcl:"ssh_proxy_password"` + SSHKeepAliveInterval *string `mapstructure:"ssh_keep_alive_interval" cty:"ssh_keep_alive_interval" hcl:"ssh_keep_alive_interval"` + SSHReadWriteTimeout *string `mapstructure:"ssh_read_write_timeout" cty:"ssh_read_write_timeout" hcl:"ssh_read_write_timeout"` + SSHRemoteTunnels []string `mapstructure:"ssh_remote_tunnels" cty:"ssh_remote_tunnels" hcl:"ssh_remote_tunnels"` + SSHLocalTunnels []string `mapstructure:"ssh_local_tunnels" cty:"ssh_local_tunnels" hcl:"ssh_local_tunnels"` + SSHPublicKey []byte `mapstructure:"ssh_public_key" undocumented:"true" cty:"ssh_public_key" hcl:"ssh_public_key"` + SSHPrivateKey []byte `mapstructure:"ssh_private_key" undocumented:"true" cty:"ssh_private_key" hcl:"ssh_private_key"` + WinRMUser *string `mapstructure:"winrm_username" cty:"winrm_username" hcl:"winrm_username"` + WinRMPassword *string `mapstructure:"winrm_password" cty:"winrm_password" hcl:"winrm_password"` + WinRMHost *string `mapstructure:"winrm_host" cty:"winrm_host" hcl:"winrm_host"` + WinRMNoProxy *bool `mapstructure:"winrm_no_proxy" cty:"winrm_no_proxy" hcl:"winrm_no_proxy"` + WinRMPort *int `mapstructure:"winrm_port" cty:"winrm_port" hcl:"winrm_port"` + WinRMTimeout *string `mapstructure:"winrm_timeout" cty:"winrm_timeout" hcl:"winrm_timeout"` + WinRMUseSSL *bool `mapstructure:"winrm_use_ssl" cty:"winrm_use_ssl" hcl:"winrm_use_ssl"` + WinRMInsecure *bool `mapstructure:"winrm_insecure" cty:"winrm_insecure" hcl:"winrm_insecure"` + WinRMUseNTLM *bool `mapstructure:"winrm_use_ntlm" cty:"winrm_use_ntlm" hcl:"winrm_use_ntlm"` + ProxmoxURLRaw *string `mapstructure:"proxmox_url" cty:"proxmox_url" hcl:"proxmox_url"` + SkipCertValidation *bool `mapstructure:"insecure_skip_tls_verify" cty:"insecure_skip_tls_verify" hcl:"insecure_skip_tls_verify"` + Username *string `mapstructure:"username" cty:"username" hcl:"username"` + Password *string `mapstructure:"password" cty:"password" hcl:"password"` + Node *string `mapstructure:"node" cty:"node" hcl:"node"` + Pool *string `mapstructure:"pool" cty:"pool" hcl:"pool"` + VMName *string `mapstructure:"vm_name" cty:"vm_name" hcl:"vm_name"` + VMID *int `mapstructure:"vm_id" cty:"vm_id" hcl:"vm_id"` + Memory *int `mapstructure:"memory" cty:"memory" hcl:"memory"` + Cores *int `mapstructure:"cores" cty:"cores" hcl:"cores"` + CPUType *string `mapstructure:"cpu_type" cty:"cpu_type" hcl:"cpu_type"` + Sockets *int `mapstructure:"sockets" cty:"sockets" hcl:"sockets"` + OS *string `mapstructure:"os" cty:"os" hcl:"os"` + VGA *FlatvgaConfig `mapstructure:"vga" cty:"vga" hcl:"vga"` + NICs []FlatnicConfig `mapstructure:"network_adapters" cty:"network_adapters" hcl:"network_adapters"` + Disks []FlatdiskConfig `mapstructure:"disks" cty:"disks" hcl:"disks"` + ISOFile *string `mapstructure:"iso_file" cty:"iso_file" hcl:"iso_file"` + ISOStoragePool *string `mapstructure:"iso_storage_pool" cty:"iso_storage_pool" hcl:"iso_storage_pool"` + Agent *bool `mapstructure:"qemu_agent" cty:"qemu_agent" hcl:"qemu_agent"` + SCSIController *string `mapstructure:"scsi_controller" cty:"scsi_controller" hcl:"scsi_controller"` + Onboot *bool `mapstructure:"onboot" cty:"onboot" hcl:"onboot"` + DisableKVM *bool `mapstructure:"disable_kvm" cty:"disable_kvm" hcl:"disable_kvm"` + TemplateName *string `mapstructure:"template_name" cty:"template_name" hcl:"template_name"` + TemplateDescription *string `mapstructure:"template_description" cty:"template_description" hcl:"template_description"` + UnmountISO *bool `mapstructure:"unmount_iso" cty:"unmount_iso" hcl:"unmount_iso"` + CloudInit *bool `mapstructure:"cloud_init" cty:"cloud_init" hcl:"cloud_init"` + CloudInitStoragePool *string `mapstructure:"cloud_init_storage_pool" cty:"cloud_init_storage_pool" hcl:"cloud_init_storage_pool"` + AdditionalISOFiles []FlatstorageConfig `mapstructure:"additional_iso_files" cty:"additional_iso_files" hcl:"additional_iso_files"` } // FlatMapstructure returns a new FlatConfig. @@ -211,6 +212,7 @@ func (*FlatConfig) HCL2Spec() map[string]hcldec.Spec { "unmount_iso": &hcldec.AttrSpec{Name: "unmount_iso", Type: cty.Bool, Required: false}, "cloud_init": &hcldec.AttrSpec{Name: "cloud_init", Type: cty.Bool, Required: false}, "cloud_init_storage_pool": &hcldec.AttrSpec{Name: "cloud_init_storage_pool", Type: cty.String, Required: false}, + "additional_iso_files": &hcldec.BlockListSpec{TypeName: "additional_iso_files", Nested: hcldec.ObjectSpec((*FlatstorageConfig)(nil).HCL2Spec())}, } return s } @@ -281,6 +283,33 @@ func (*FlatnicConfig) HCL2Spec() map[string]hcldec.Spec { return s } +// FlatstorageConfig is an auto-generated flat version of storageConfig. +// Where the contents of a field with a `mapstructure:,squash` tag are bubbled up. +type FlatstorageConfig struct { + Device *string `mapstructure:"device" cty:"device" hcl:"device"` + BusNumber *int `mapstructure:"bus_number" cty:"bus_number" hcl:"bus_number"` + Filename *string `mapstructure:"filename" cty:"filename" hcl:"filename"` +} + +// FlatMapstructure returns a new FlatstorageConfig. +// FlatstorageConfig is an auto-generated flat version of storageConfig. +// Where the contents a fields with a `mapstructure:,squash` tag are bubbled up. +func (*storageConfig) FlatMapstructure() interface{ HCL2Spec() map[string]hcldec.Spec } { + return new(FlatstorageConfig) +} + +// HCL2Spec returns the hcl spec of a storageConfig. +// This spec is used by HCL to read the fields of storageConfig. +// The decoded values from this spec will then be applied to a FlatstorageConfig. +func (*FlatstorageConfig) HCL2Spec() map[string]hcldec.Spec { + s := map[string]hcldec.Spec{ + "device": &hcldec.AttrSpec{Name: "device", Type: cty.String, Required: false}, + "bus_number": &hcldec.AttrSpec{Name: "bus_number", Type: cty.Number, Required: false}, + "filename": &hcldec.AttrSpec{Name: "filename", Type: cty.String, Required: false}, + } + return s +} + // FlatvgaConfig is an auto-generated flat version of vgaConfig. // Where the contents of a field with a `mapstructure:,squash` tag are bubbled up. type FlatvgaConfig struct { diff --git a/builder/proxmox/step_start_vm.go b/builder/proxmox/step_start_vm.go index f44fbf31508..4e615b67ede 100644 --- a/builder/proxmox/step_start_vm.go +++ b/builder/proxmox/step_start_vm.go @@ -91,6 +91,19 @@ func (s *stepStartVM) Run(ctx context.Context, state multistep.StateBag) multist // instance id inside of the provisioners, used in step_provision. state.Put("instance_id", vmRef) + for idx := range c.AdditionalISOFiles { + params := map[string]interface{}{ + c.AdditionalISOFiles[idx].Device + strconv.Itoa(c.AdditionalISOFiles[idx].BusNumber): c.AdditionalISOFiles[idx].Filename + ",media=cdrom", + } + _, err = client.SetVmConfig(vmRef, params) + if err != nil { + err := fmt.Errorf("Error configuring VM: %s", err) + state.Put("error", err) + ui.Error(err.Error()) + return multistep.ActionHalt + } + } + //LOOK HERE, add the error msg to AdditionalISOFiles SetVmConfig same as below ui.Say("Starting VM") _, err = client.StartVm(vmRef) if err != nil { diff --git a/website/pages/docs/builders/proxmox.mdx b/website/pages/docs/builders/proxmox.mdx index 339a7accd98..0fd6d555217 100644 --- a/website/pages/docs/builders/proxmox.mdx +++ b/website/pages/docs/builders/proxmox.mdx @@ -141,7 +141,7 @@ builder. - `firewall` (bool) - If the interface should be protected by the firewall. Defaults to `false`. - + - `packet_queues` (int) - Number of packet queues to be used on the device. Values greater than 1 indicate that the multiqueue feature is activated. For best performance, set this to the number of cores available to the @@ -213,6 +213,27 @@ builder. - `cloud_init_storage_pool` - (string) - Name of the Proxmox storage pool to store the Cloud-Init CDROM on. If not given, the storage pool of the boot device will be used. +- `additional_iso_files` (array of objects) - Additional ISO filess attached to the virtual machine. + Example: + + ```json + [ + { + "device": "scsi", + "bus_number": "3", + "filemane": "local:iso/virtio-win-0.1.185.iso" + } + ] + ``` + - `device` (string) - Bus type that the ISO will be mountet on. Can be `ide`, + `sata` or `scsi`. + Defaults to `ide`. + + - `bus_number` (string) - Number of the device. Can be 0 to 3 for `ide`, 0 to 5 + for `sata` and 0 to 30 for `scsi`. + Defaults to 3 sice `ide` bus 2 is generally the boot drive. + + - `filename` (string) - Required. Path to the ISO file that will be mounted, expressed as a Proxmox datastore path. ## Example: Fedora with kickstart Here is a basic example creating a Fedora 29 server image with a Kickstart