Add ovf export capability to vsphere builders (#8764)
* add ovf export capability to vsphere builders * remove unneeded floppy ejection * add prepare step for export. updated output directory to be the actual destination directory * add step export documentation * add extra export options * add ui messages for export step Co-authored-by: Megan Marsh <megan@hashicorp.com> Co-authored-by: Wilken Rivera <dev@wilkenrivera.com>
This commit is contained in:
parent
9aba27bc83
commit
99b0b98311
|
@ -82,6 +82,17 @@ func (b *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (pack
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if b.config.Export != nil {
|
||||||
|
steps = append(steps, &common.StepExport{
|
||||||
|
Name: b.config.Export.Name,
|
||||||
|
Force: b.config.Export.Force,
|
||||||
|
Images: b.config.Export.Images,
|
||||||
|
Manifest: b.config.Export.Manifest,
|
||||||
|
OutputDir: b.config.Export.OutputDir.OutputDir,
|
||||||
|
Options: b.config.Export.Options,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
b.runner = packerCommon.NewRunner(steps, b.config.PackerConfig, ui)
|
b.runner = packerCommon.NewRunner(steps, b.config.PackerConfig, ui)
|
||||||
b.runner.Run(ctx, state)
|
b.runner.Run(ctx, state)
|
||||||
|
|
||||||
|
|
|
@ -32,6 +32,8 @@ type Config struct {
|
||||||
// Convert VM to a template. Defaults to `false`.
|
// Convert VM to a template. Defaults to `false`.
|
||||||
ConvertToTemplate bool `mapstructure:"convert_to_template"`
|
ConvertToTemplate bool `mapstructure:"convert_to_template"`
|
||||||
|
|
||||||
|
Export *common.ExportConfig `mapstructure:"export"`
|
||||||
|
|
||||||
ctx interpolate.Context
|
ctx interpolate.Context
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -53,6 +55,9 @@ func (c *Config) Prepare(raws ...interface{}) ([]string, error) {
|
||||||
errs = packer.MultiErrorAppend(errs, c.WaitIpConfig.Prepare()...)
|
errs = packer.MultiErrorAppend(errs, c.WaitIpConfig.Prepare()...)
|
||||||
errs = packer.MultiErrorAppend(errs, c.Comm.Prepare(&c.ctx)...)
|
errs = packer.MultiErrorAppend(errs, c.Comm.Prepare(&c.ctx)...)
|
||||||
errs = packer.MultiErrorAppend(errs, c.ShutdownConfig.Prepare()...)
|
errs = packer.MultiErrorAppend(errs, c.ShutdownConfig.Prepare()...)
|
||||||
|
if c.Export != nil {
|
||||||
|
errs = packer.MultiErrorAppend(errs, c.Export.Prepare(&c.ctx, &c.LocationConfig, &c.PackerConfig)...)
|
||||||
|
}
|
||||||
|
|
||||||
if len(errs.Errors) > 0 {
|
if len(errs.Errors) > 0 {
|
||||||
return nil, errs
|
return nil, errs
|
||||||
|
|
|
@ -3,95 +3,97 @@ package clone
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/hashicorp/hcl/v2/hcldec"
|
"github.com/hashicorp/hcl/v2/hcldec"
|
||||||
|
"github.com/hashicorp/packer/builder/vsphere/common"
|
||||||
"github.com/zclconf/go-cty/cty"
|
"github.com/zclconf/go-cty/cty"
|
||||||
)
|
)
|
||||||
|
|
||||||
// FlatConfig is an auto-generated flat version of Config.
|
// FlatConfig is an auto-generated flat version of Config.
|
||||||
// Where the contents of a field with a `mapstructure:,squash` tag are bubbled up.
|
// Where the contents of a field with a `mapstructure:,squash` tag are bubbled up.
|
||||||
type FlatConfig struct {
|
type FlatConfig struct {
|
||||||
PackerBuildName *string `mapstructure:"packer_build_name" cty:"packer_build_name"`
|
PackerBuildName *string `mapstructure:"packer_build_name" cty:"packer_build_name"`
|
||||||
PackerBuilderType *string `mapstructure:"packer_builder_type" cty:"packer_builder_type"`
|
PackerBuilderType *string `mapstructure:"packer_builder_type" cty:"packer_builder_type"`
|
||||||
PackerDebug *bool `mapstructure:"packer_debug" cty:"packer_debug"`
|
PackerDebug *bool `mapstructure:"packer_debug" cty:"packer_debug"`
|
||||||
PackerForce *bool `mapstructure:"packer_force" cty:"packer_force"`
|
PackerForce *bool `mapstructure:"packer_force" cty:"packer_force"`
|
||||||
PackerOnError *string `mapstructure:"packer_on_error" cty:"packer_on_error"`
|
PackerOnError *string `mapstructure:"packer_on_error" cty:"packer_on_error"`
|
||||||
PackerUserVars map[string]string `mapstructure:"packer_user_variables" cty:"packer_user_variables"`
|
PackerUserVars map[string]string `mapstructure:"packer_user_variables" cty:"packer_user_variables"`
|
||||||
PackerSensitiveVars []string `mapstructure:"packer_sensitive_variables" cty:"packer_sensitive_variables"`
|
PackerSensitiveVars []string `mapstructure:"packer_sensitive_variables" cty:"packer_sensitive_variables"`
|
||||||
VCenterServer *string `mapstructure:"vcenter_server" cty:"vcenter_server"`
|
VCenterServer *string `mapstructure:"vcenter_server" cty:"vcenter_server"`
|
||||||
Username *string `mapstructure:"username" cty:"username"`
|
Username *string `mapstructure:"username" cty:"username"`
|
||||||
Password *string `mapstructure:"password" cty:"password"`
|
Password *string `mapstructure:"password" cty:"password"`
|
||||||
InsecureConnection *bool `mapstructure:"insecure_connection" cty:"insecure_connection"`
|
InsecureConnection *bool `mapstructure:"insecure_connection" cty:"insecure_connection"`
|
||||||
Datacenter *string `mapstructure:"datacenter" cty:"datacenter"`
|
Datacenter *string `mapstructure:"datacenter" cty:"datacenter"`
|
||||||
Template *string `mapstructure:"template" cty:"template"`
|
Template *string `mapstructure:"template" cty:"template"`
|
||||||
DiskSize *int64 `mapstructure:"disk_size" cty:"disk_size"`
|
DiskSize *int64 `mapstructure:"disk_size" cty:"disk_size"`
|
||||||
LinkedClone *bool `mapstructure:"linked_clone" cty:"linked_clone"`
|
LinkedClone *bool `mapstructure:"linked_clone" cty:"linked_clone"`
|
||||||
Network *string `mapstructure:"network" cty:"network"`
|
Network *string `mapstructure:"network" cty:"network"`
|
||||||
Notes *string `mapstructure:"notes" cty:"notes"`
|
Notes *string `mapstructure:"notes" cty:"notes"`
|
||||||
VMName *string `mapstructure:"vm_name" cty:"vm_name"`
|
VMName *string `mapstructure:"vm_name" cty:"vm_name"`
|
||||||
Folder *string `mapstructure:"folder" cty:"folder"`
|
Folder *string `mapstructure:"folder" cty:"folder"`
|
||||||
Cluster *string `mapstructure:"cluster" cty:"cluster"`
|
Cluster *string `mapstructure:"cluster" cty:"cluster"`
|
||||||
Host *string `mapstructure:"host" cty:"host"`
|
Host *string `mapstructure:"host" cty:"host"`
|
||||||
ResourcePool *string `mapstructure:"resource_pool" cty:"resource_pool"`
|
ResourcePool *string `mapstructure:"resource_pool" cty:"resource_pool"`
|
||||||
Datastore *string `mapstructure:"datastore" cty:"datastore"`
|
Datastore *string `mapstructure:"datastore" cty:"datastore"`
|
||||||
CPUs *int32 `mapstructure:"CPUs" cty:"CPUs"`
|
CPUs *int32 `mapstructure:"CPUs" cty:"CPUs"`
|
||||||
CpuCores *int32 `mapstructure:"cpu_cores" cty:"cpu_cores"`
|
CpuCores *int32 `mapstructure:"cpu_cores" cty:"cpu_cores"`
|
||||||
CPUReservation *int64 `mapstructure:"CPU_reservation" cty:"CPU_reservation"`
|
CPUReservation *int64 `mapstructure:"CPU_reservation" cty:"CPU_reservation"`
|
||||||
CPULimit *int64 `mapstructure:"CPU_limit" cty:"CPU_limit"`
|
CPULimit *int64 `mapstructure:"CPU_limit" cty:"CPU_limit"`
|
||||||
CpuHotAddEnabled *bool `mapstructure:"CPU_hot_plug" cty:"CPU_hot_plug"`
|
CpuHotAddEnabled *bool `mapstructure:"CPU_hot_plug" cty:"CPU_hot_plug"`
|
||||||
RAM *int64 `mapstructure:"RAM" cty:"RAM"`
|
RAM *int64 `mapstructure:"RAM" cty:"RAM"`
|
||||||
RAMReservation *int64 `mapstructure:"RAM_reservation" cty:"RAM_reservation"`
|
RAMReservation *int64 `mapstructure:"RAM_reservation" cty:"RAM_reservation"`
|
||||||
RAMReserveAll *bool `mapstructure:"RAM_reserve_all" cty:"RAM_reserve_all"`
|
RAMReserveAll *bool `mapstructure:"RAM_reserve_all" cty:"RAM_reserve_all"`
|
||||||
MemoryHotAddEnabled *bool `mapstructure:"RAM_hot_plug" cty:"RAM_hot_plug"`
|
MemoryHotAddEnabled *bool `mapstructure:"RAM_hot_plug" cty:"RAM_hot_plug"`
|
||||||
VideoRAM *int64 `mapstructure:"video_ram" cty:"video_ram"`
|
VideoRAM *int64 `mapstructure:"video_ram" cty:"video_ram"`
|
||||||
NestedHV *bool `mapstructure:"NestedHV" cty:"NestedHV"`
|
NestedHV *bool `mapstructure:"NestedHV" cty:"NestedHV"`
|
||||||
ConfigParams map[string]string `mapstructure:"configuration_parameters" cty:"configuration_parameters"`
|
ConfigParams map[string]string `mapstructure:"configuration_parameters" cty:"configuration_parameters"`
|
||||||
BootOrder *string `mapstructure:"boot_order" cty:"boot_order"`
|
BootOrder *string `mapstructure:"boot_order" cty:"boot_order"`
|
||||||
WaitTimeout *string `mapstructure:"ip_wait_timeout" cty:"ip_wait_timeout"`
|
WaitTimeout *string `mapstructure:"ip_wait_timeout" cty:"ip_wait_timeout"`
|
||||||
SettleTimeout *string `mapstructure:"ip_settle_timeout" cty:"ip_settle_timeout"`
|
SettleTimeout *string `mapstructure:"ip_settle_timeout" cty:"ip_settle_timeout"`
|
||||||
Type *string `mapstructure:"communicator" cty:"communicator"`
|
Type *string `mapstructure:"communicator" cty:"communicator"`
|
||||||
PauseBeforeConnect *string `mapstructure:"pause_before_connecting" cty:"pause_before_connecting"`
|
PauseBeforeConnect *string `mapstructure:"pause_before_connecting" cty:"pause_before_connecting"`
|
||||||
SSHHost *string `mapstructure:"ssh_host" cty:"ssh_host"`
|
SSHHost *string `mapstructure:"ssh_host" cty:"ssh_host"`
|
||||||
SSHPort *int `mapstructure:"ssh_port" cty:"ssh_port"`
|
SSHPort *int `mapstructure:"ssh_port" cty:"ssh_port"`
|
||||||
SSHUsername *string `mapstructure:"ssh_username" cty:"ssh_username"`
|
SSHUsername *string `mapstructure:"ssh_username" cty:"ssh_username"`
|
||||||
SSHPassword *string `mapstructure:"ssh_password" cty:"ssh_password"`
|
SSHPassword *string `mapstructure:"ssh_password" cty:"ssh_password"`
|
||||||
SSHKeyPairName *string `mapstructure:"ssh_keypair_name" cty:"ssh_keypair_name"`
|
SSHKeyPairName *string `mapstructure:"ssh_keypair_name" cty:"ssh_keypair_name"`
|
||||||
SSHTemporaryKeyPairName *string `mapstructure:"temporary_key_pair_name" cty:"temporary_key_pair_name"`
|
SSHTemporaryKeyPairName *string `mapstructure:"temporary_key_pair_name" cty:"temporary_key_pair_name"`
|
||||||
SSHClearAuthorizedKeys *bool `mapstructure:"ssh_clear_authorized_keys" cty:"ssh_clear_authorized_keys"`
|
SSHClearAuthorizedKeys *bool `mapstructure:"ssh_clear_authorized_keys" cty:"ssh_clear_authorized_keys"`
|
||||||
SSHPrivateKeyFile *string `mapstructure:"ssh_private_key_file" cty:"ssh_private_key_file"`
|
SSHPrivateKeyFile *string `mapstructure:"ssh_private_key_file" cty:"ssh_private_key_file"`
|
||||||
SSHPty *bool `mapstructure:"ssh_pty" cty:"ssh_pty"`
|
SSHPty *bool `mapstructure:"ssh_pty" cty:"ssh_pty"`
|
||||||
SSHTimeout *string `mapstructure:"ssh_timeout" cty:"ssh_timeout"`
|
SSHTimeout *string `mapstructure:"ssh_timeout" cty:"ssh_timeout"`
|
||||||
SSHAgentAuth *bool `mapstructure:"ssh_agent_auth" cty:"ssh_agent_auth"`
|
SSHAgentAuth *bool `mapstructure:"ssh_agent_auth" cty:"ssh_agent_auth"`
|
||||||
SSHDisableAgentForwarding *bool `mapstructure:"ssh_disable_agent_forwarding" cty:"ssh_disable_agent_forwarding"`
|
SSHDisableAgentForwarding *bool `mapstructure:"ssh_disable_agent_forwarding" cty:"ssh_disable_agent_forwarding"`
|
||||||
SSHHandshakeAttempts *int `mapstructure:"ssh_handshake_attempts" cty:"ssh_handshake_attempts"`
|
SSHHandshakeAttempts *int `mapstructure:"ssh_handshake_attempts" cty:"ssh_handshake_attempts"`
|
||||||
SSHBastionHost *string `mapstructure:"ssh_bastion_host" cty:"ssh_bastion_host"`
|
SSHBastionHost *string `mapstructure:"ssh_bastion_host" cty:"ssh_bastion_host"`
|
||||||
SSHBastionPort *int `mapstructure:"ssh_bastion_port" cty:"ssh_bastion_port"`
|
SSHBastionPort *int `mapstructure:"ssh_bastion_port" cty:"ssh_bastion_port"`
|
||||||
SSHBastionAgentAuth *bool `mapstructure:"ssh_bastion_agent_auth" cty:"ssh_bastion_agent_auth"`
|
SSHBastionAgentAuth *bool `mapstructure:"ssh_bastion_agent_auth" cty:"ssh_bastion_agent_auth"`
|
||||||
SSHBastionUsername *string `mapstructure:"ssh_bastion_username" cty:"ssh_bastion_username"`
|
SSHBastionUsername *string `mapstructure:"ssh_bastion_username" cty:"ssh_bastion_username"`
|
||||||
SSHBastionPassword *string `mapstructure:"ssh_bastion_password" cty:"ssh_bastion_password"`
|
SSHBastionPassword *string `mapstructure:"ssh_bastion_password" cty:"ssh_bastion_password"`
|
||||||
SSHBastionInteractive *bool `mapstructure:"ssh_bastion_interactive" cty:"ssh_bastion_interactive"`
|
SSHBastionInteractive *bool `mapstructure:"ssh_bastion_interactive" cty:"ssh_bastion_interactive"`
|
||||||
SSHBastionPrivateKeyFile *string `mapstructure:"ssh_bastion_private_key_file" cty:"ssh_bastion_private_key_file"`
|
SSHBastionPrivateKeyFile *string `mapstructure:"ssh_bastion_private_key_file" cty:"ssh_bastion_private_key_file"`
|
||||||
SSHFileTransferMethod *string `mapstructure:"ssh_file_transfer_method" cty:"ssh_file_transfer_method"`
|
SSHFileTransferMethod *string `mapstructure:"ssh_file_transfer_method" cty:"ssh_file_transfer_method"`
|
||||||
SSHProxyHost *string `mapstructure:"ssh_proxy_host" cty:"ssh_proxy_host"`
|
SSHProxyHost *string `mapstructure:"ssh_proxy_host" cty:"ssh_proxy_host"`
|
||||||
SSHProxyPort *int `mapstructure:"ssh_proxy_port" cty:"ssh_proxy_port"`
|
SSHProxyPort *int `mapstructure:"ssh_proxy_port" cty:"ssh_proxy_port"`
|
||||||
SSHProxyUsername *string `mapstructure:"ssh_proxy_username" cty:"ssh_proxy_username"`
|
SSHProxyUsername *string `mapstructure:"ssh_proxy_username" cty:"ssh_proxy_username"`
|
||||||
SSHProxyPassword *string `mapstructure:"ssh_proxy_password" cty:"ssh_proxy_password"`
|
SSHProxyPassword *string `mapstructure:"ssh_proxy_password" cty:"ssh_proxy_password"`
|
||||||
SSHKeepAliveInterval *string `mapstructure:"ssh_keep_alive_interval" cty:"ssh_keep_alive_interval"`
|
SSHKeepAliveInterval *string `mapstructure:"ssh_keep_alive_interval" cty:"ssh_keep_alive_interval"`
|
||||||
SSHReadWriteTimeout *string `mapstructure:"ssh_read_write_timeout" cty:"ssh_read_write_timeout"`
|
SSHReadWriteTimeout *string `mapstructure:"ssh_read_write_timeout" cty:"ssh_read_write_timeout"`
|
||||||
SSHRemoteTunnels []string `mapstructure:"ssh_remote_tunnels" cty:"ssh_remote_tunnels"`
|
SSHRemoteTunnels []string `mapstructure:"ssh_remote_tunnels" cty:"ssh_remote_tunnels"`
|
||||||
SSHLocalTunnels []string `mapstructure:"ssh_local_tunnels" cty:"ssh_local_tunnels"`
|
SSHLocalTunnels []string `mapstructure:"ssh_local_tunnels" cty:"ssh_local_tunnels"`
|
||||||
SSHPublicKey []byte `mapstructure:"ssh_public_key" cty:"ssh_public_key"`
|
SSHPublicKey []byte `mapstructure:"ssh_public_key" cty:"ssh_public_key"`
|
||||||
SSHPrivateKey []byte `mapstructure:"ssh_private_key" cty:"ssh_private_key"`
|
SSHPrivateKey []byte `mapstructure:"ssh_private_key" cty:"ssh_private_key"`
|
||||||
WinRMUser *string `mapstructure:"winrm_username" cty:"winrm_username"`
|
WinRMUser *string `mapstructure:"winrm_username" cty:"winrm_username"`
|
||||||
WinRMPassword *string `mapstructure:"winrm_password" cty:"winrm_password"`
|
WinRMPassword *string `mapstructure:"winrm_password" cty:"winrm_password"`
|
||||||
WinRMHost *string `mapstructure:"winrm_host" cty:"winrm_host"`
|
WinRMHost *string `mapstructure:"winrm_host" cty:"winrm_host"`
|
||||||
WinRMPort *int `mapstructure:"winrm_port" cty:"winrm_port"`
|
WinRMPort *int `mapstructure:"winrm_port" cty:"winrm_port"`
|
||||||
WinRMTimeout *string `mapstructure:"winrm_timeout" cty:"winrm_timeout"`
|
WinRMTimeout *string `mapstructure:"winrm_timeout" cty:"winrm_timeout"`
|
||||||
WinRMUseSSL *bool `mapstructure:"winrm_use_ssl" cty:"winrm_use_ssl"`
|
WinRMUseSSL *bool `mapstructure:"winrm_use_ssl" cty:"winrm_use_ssl"`
|
||||||
WinRMInsecure *bool `mapstructure:"winrm_insecure" cty:"winrm_insecure"`
|
WinRMInsecure *bool `mapstructure:"winrm_insecure" cty:"winrm_insecure"`
|
||||||
WinRMUseNTLM *bool `mapstructure:"winrm_use_ntlm" cty:"winrm_use_ntlm"`
|
WinRMUseNTLM *bool `mapstructure:"winrm_use_ntlm" cty:"winrm_use_ntlm"`
|
||||||
Command *string `mapstructure:"shutdown_command" cty:"shutdown_command"`
|
Command *string `mapstructure:"shutdown_command" cty:"shutdown_command"`
|
||||||
Timeout *string `mapstructure:"shutdown_timeout" cty:"shutdown_timeout"`
|
Timeout *string `mapstructure:"shutdown_timeout" cty:"shutdown_timeout"`
|
||||||
CreateSnapshot *bool `mapstructure:"create_snapshot" cty:"create_snapshot"`
|
CreateSnapshot *bool `mapstructure:"create_snapshot" cty:"create_snapshot"`
|
||||||
ConvertToTemplate *bool `mapstructure:"convert_to_template" cty:"convert_to_template"`
|
ConvertToTemplate *bool `mapstructure:"convert_to_template" cty:"convert_to_template"`
|
||||||
|
Export *common.FlatExportConfig `mapstructure:"export" cty:"export"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// FlatMapstructure returns a new FlatConfig.
|
// FlatMapstructure returns a new FlatConfig.
|
||||||
|
@ -189,6 +191,7 @@ func (*FlatConfig) HCL2Spec() map[string]hcldec.Spec {
|
||||||
"shutdown_timeout": &hcldec.AttrSpec{Name: "shutdown_timeout", Type: cty.String, Required: false},
|
"shutdown_timeout": &hcldec.AttrSpec{Name: "shutdown_timeout", Type: cty.String, Required: false},
|
||||||
"create_snapshot": &hcldec.AttrSpec{Name: "create_snapshot", Type: cty.Bool, Required: false},
|
"create_snapshot": &hcldec.AttrSpec{Name: "create_snapshot", Type: cty.Bool, Required: false},
|
||||||
"convert_to_template": &hcldec.AttrSpec{Name: "convert_to_template", Type: cty.Bool, Required: false},
|
"convert_to_template": &hcldec.AttrSpec{Name: "convert_to_template", Type: cty.Bool, Required: false},
|
||||||
|
"export": &hcldec.BlockSpec{TypeName: "export", Nested: hcldec.ObjectSpec((*common.FlatExportConfig)(nil).HCL2Spec())},
|
||||||
}
|
}
|
||||||
return s
|
return s
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,30 @@
|
||||||
|
//go:generate struct-markdown
|
||||||
|
//go:generate mapstructure-to-hcl2 -type OutputConfig
|
||||||
|
|
||||||
|
package common
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/hashicorp/packer/common"
|
||||||
|
"github.com/hashicorp/packer/template/interpolate"
|
||||||
|
)
|
||||||
|
|
||||||
|
type OutputConfig struct {
|
||||||
|
// This setting specifies the directory that
|
||||||
|
// artifacts from the build, such as the virtual machine files and disks,
|
||||||
|
// will be output to. The path to the directory may be relative or
|
||||||
|
// absolute. If relative, the path is relative to the working directory
|
||||||
|
// packer is executed from. This directory must not exist or, if
|
||||||
|
// created, must be empty prior to running the builder. By default this is
|
||||||
|
// "output-BUILDNAME" where "BUILDNAME" is the name of the build.
|
||||||
|
OutputDir string `mapstructure:"output_directory" required:"false"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *OutputConfig) Prepare(ctx *interpolate.Context, pc *common.PackerConfig) []error {
|
||||||
|
if c.OutputDir == "" {
|
||||||
|
c.OutputDir = fmt.Sprintf("output-%s", pc.PackerBuildName)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
|
@ -0,0 +1,30 @@
|
||||||
|
// Code generated by "mapstructure-to-hcl2 -type OutputConfig"; DO NOT EDIT.
|
||||||
|
package common
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/hashicorp/hcl/v2/hcldec"
|
||||||
|
"github.com/zclconf/go-cty/cty"
|
||||||
|
)
|
||||||
|
|
||||||
|
// FlatOutputConfig is an auto-generated flat version of OutputConfig.
|
||||||
|
// Where the contents of a field with a `mapstructure:,squash` tag are bubbled up.
|
||||||
|
type FlatOutputConfig struct {
|
||||||
|
OutputDir *string `mapstructure:"output_directory" required:"false" cty:"output_directory"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// FlatMapstructure returns a new FlatOutputConfig.
|
||||||
|
// FlatOutputConfig is an auto-generated flat version of OutputConfig.
|
||||||
|
// Where the contents a fields with a `mapstructure:,squash` tag are bubbled up.
|
||||||
|
func (*OutputConfig) FlatMapstructure() interface{ HCL2Spec() map[string]hcldec.Spec } {
|
||||||
|
return new(FlatOutputConfig)
|
||||||
|
}
|
||||||
|
|
||||||
|
// HCL2Spec returns the hcl spec of a OutputConfig.
|
||||||
|
// This spec is used by HCL to read the fields of OutputConfig.
|
||||||
|
// The decoded values from this spec will then be applied to a FlatOutputConfig.
|
||||||
|
func (*FlatOutputConfig) HCL2Spec() map[string]hcldec.Spec {
|
||||||
|
s := map[string]hcldec.Spec{
|
||||||
|
"output_directory": &hcldec.AttrSpec{Name: "output_directory", Type: cty.String, Required: false},
|
||||||
|
}
|
||||||
|
return s
|
||||||
|
}
|
|
@ -0,0 +1,304 @@
|
||||||
|
//go:generate struct-markdown
|
||||||
|
//go:generate mapstructure-to-hcl2 -type ExportConfig
|
||||||
|
|
||||||
|
package common
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"context"
|
||||||
|
"crypto/sha1"
|
||||||
|
"crypto/sha256"
|
||||||
|
"crypto/sha512"
|
||||||
|
"fmt"
|
||||||
|
"hash"
|
||||||
|
"io"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/hashicorp/packer/builder/vsphere/driver"
|
||||||
|
"github.com/hashicorp/packer/common"
|
||||||
|
"github.com/hashicorp/packer/helper/multistep"
|
||||||
|
"github.com/hashicorp/packer/packer"
|
||||||
|
"github.com/hashicorp/packer/template/interpolate"
|
||||||
|
"github.com/pkg/errors"
|
||||||
|
"github.com/vmware/govmomi/nfc"
|
||||||
|
"github.com/vmware/govmomi/vim25/soap"
|
||||||
|
"github.com/vmware/govmomi/vim25/types"
|
||||||
|
)
|
||||||
|
|
||||||
|
// You may optionally export an ovf from VSphere to the instance running Packer.
|
||||||
|
//
|
||||||
|
// Example usage:
|
||||||
|
//
|
||||||
|
// ```json
|
||||||
|
// ...
|
||||||
|
// "vm_name": "example-ubuntu",
|
||||||
|
// ...
|
||||||
|
// "export": {
|
||||||
|
// "force": true,
|
||||||
|
// "output_directory": "./output_vsphere"
|
||||||
|
// },
|
||||||
|
// ```
|
||||||
|
// The above configuration would create the following files:
|
||||||
|
//
|
||||||
|
// ```
|
||||||
|
// ./output_vsphere/example-ubuntu-disk-0.vmdk
|
||||||
|
// ./output_vsphere/example-ubuntu.mf
|
||||||
|
// ./output_vsphere/example-ubuntu.ovf
|
||||||
|
// ```
|
||||||
|
type ExportConfig struct {
|
||||||
|
// name of the ovf. defaults to the name of the VM
|
||||||
|
Name string `mapstructure:"name"`
|
||||||
|
// overwrite ovf if it exists
|
||||||
|
Force bool `mapstructure:"force"`
|
||||||
|
// include iso and img image files that are attached to the VM
|
||||||
|
Images bool `mapstructure:"images"`
|
||||||
|
// generate manifest using sha1, sha256, sha512. Defaults to 'sha256'. Use 'none' for no manifest.
|
||||||
|
Manifest string `mapstructure:"manifest"`
|
||||||
|
OutputDir OutputConfig `mapstructure:",squash"`
|
||||||
|
// Advanced ovf export options. Options can include:
|
||||||
|
// * mac - MAC address is exported for all ethernet devices
|
||||||
|
// * uuid - UUID is exported for all virtual machines
|
||||||
|
// * extraconfig - all extra configuration options are exported for a virtual machine
|
||||||
|
// * nodevicesubtypes - resource subtypes for CD/DVD drives, floppy drives, and serial and parallel ports are not exported
|
||||||
|
//
|
||||||
|
// For example, adding the following export config option would output the mac addresses for all Ethernet devices in the ovf file:
|
||||||
|
|
||||||
|
// ```json
|
||||||
|
// ...
|
||||||
|
// "export": {
|
||||||
|
// "options": ["mac"]
|
||||||
|
// },
|
||||||
|
// ```
|
||||||
|
Options []string `mapstructure:"options"`
|
||||||
|
}
|
||||||
|
|
||||||
|
var sha = map[string]func() hash.Hash{
|
||||||
|
"none": nil,
|
||||||
|
"sha1": sha1.New,
|
||||||
|
"sha256": sha256.New,
|
||||||
|
"sha512": sha512.New,
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *ExportConfig) Prepare(ctx *interpolate.Context, lc *LocationConfig, pc *common.PackerConfig) []error {
|
||||||
|
var errs *packer.MultiError
|
||||||
|
|
||||||
|
errs = packer.MultiErrorAppend(errs, c.OutputDir.Prepare(ctx, pc)...)
|
||||||
|
|
||||||
|
// manifest should default to sha256
|
||||||
|
if c.Manifest == "" {
|
||||||
|
c.Manifest = "sha256"
|
||||||
|
}
|
||||||
|
if _, ok := sha[c.Manifest]; !ok {
|
||||||
|
errs = packer.MultiErrorAppend(errs, fmt.Errorf("unknown hash: %s. available options include available options being 'none', 'sha1', 'sha256', 'sha512'", c.Manifest))
|
||||||
|
}
|
||||||
|
|
||||||
|
if c.Name == "" {
|
||||||
|
c.Name = lc.VMName
|
||||||
|
}
|
||||||
|
target := getTarget(c.OutputDir.OutputDir, c.Name)
|
||||||
|
if !c.Force {
|
||||||
|
if _, err := os.Stat(target); err == nil {
|
||||||
|
errs = packer.MultiErrorAppend(errs, fmt.Errorf("file already exists: %s", target))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := os.MkdirAll(c.OutputDir.OutputDir, 0750); err != nil {
|
||||||
|
errs = packer.MultiErrorAppend(errs, errors.Wrap(err, "unable to make directory for export"))
|
||||||
|
}
|
||||||
|
|
||||||
|
if errs != nil && len(errs.Errors) > 0 {
|
||||||
|
return errs.Errors
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func getTarget(dir string, name string) string {
|
||||||
|
return filepath.Join(dir, name+".ovf")
|
||||||
|
}
|
||||||
|
|
||||||
|
type StepExport struct {
|
||||||
|
Name string
|
||||||
|
Force bool
|
||||||
|
Images bool
|
||||||
|
Manifest string
|
||||||
|
OutputDir string
|
||||||
|
Options []string
|
||||||
|
mf bytes.Buffer
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *StepExport) Cleanup(multistep.StateBag) {
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *StepExport) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction {
|
||||||
|
ui := state.Get("ui").(packer.Ui)
|
||||||
|
vm := state.Get("vm").(*driver.VirtualMachine)
|
||||||
|
|
||||||
|
ui.Message("Starting export...")
|
||||||
|
lease, err := vm.Export()
|
||||||
|
if err != nil {
|
||||||
|
state.Put("error", errors.Wrap(err, "error exporting vm"))
|
||||||
|
return multistep.ActionHalt
|
||||||
|
}
|
||||||
|
|
||||||
|
info, err := lease.Wait(ctx, nil)
|
||||||
|
if err != nil {
|
||||||
|
state.Put("error", err)
|
||||||
|
return multistep.ActionHalt
|
||||||
|
}
|
||||||
|
|
||||||
|
u := lease.StartUpdater(ctx, info)
|
||||||
|
defer u.Done()
|
||||||
|
|
||||||
|
cdp := types.OvfCreateDescriptorParams{
|
||||||
|
Name: s.Name,
|
||||||
|
}
|
||||||
|
|
||||||
|
m := vm.NewOvfManager()
|
||||||
|
if len(s.Options) > 0 {
|
||||||
|
exportOptions, err := vm.GetOvfExportOptions(m)
|
||||||
|
if err != nil {
|
||||||
|
state.Put("error", err)
|
||||||
|
return multistep.ActionHalt
|
||||||
|
}
|
||||||
|
var unknown []string
|
||||||
|
for _, option := range s.Options {
|
||||||
|
found := false
|
||||||
|
for _, exportOpt := range exportOptions {
|
||||||
|
if exportOpt.Option == option {
|
||||||
|
found = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !found {
|
||||||
|
unknown = append(unknown, option)
|
||||||
|
}
|
||||||
|
cdp.ExportOption = append(cdp.ExportOption, option)
|
||||||
|
}
|
||||||
|
|
||||||
|
// only printing error message because the unknown options are just ignored by vcenter
|
||||||
|
if len(unknown) > 0 {
|
||||||
|
ui.Error(fmt.Sprintf("unknown export options %s", strings.Join(unknown, ",")))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, i := range info.Items {
|
||||||
|
if !s.include(&i) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if !strings.HasPrefix(i.Path, s.Name) {
|
||||||
|
i.Path = s.Name + "-" + i.Path
|
||||||
|
}
|
||||||
|
|
||||||
|
ui.Message("Downloading: " + i.File().Path)
|
||||||
|
err = s.Download(ctx, lease, i)
|
||||||
|
if err != nil {
|
||||||
|
state.Put("error", err)
|
||||||
|
return multistep.ActionHalt
|
||||||
|
}
|
||||||
|
|
||||||
|
ui.Message("Exporting file: " + i.File().Path)
|
||||||
|
cdp.OvfFiles = append(cdp.OvfFiles, i.File())
|
||||||
|
}
|
||||||
|
|
||||||
|
if err = lease.Complete(ctx); err != nil {
|
||||||
|
state.Put("error", errors.Wrap(err, "unable to complete lease"))
|
||||||
|
return multistep.ActionHalt
|
||||||
|
}
|
||||||
|
|
||||||
|
desc, err := vm.CreateDescriptor(m, cdp)
|
||||||
|
if err != nil {
|
||||||
|
state.Put("error", errors.Wrap(err, "unable to create descriptor"))
|
||||||
|
return multistep.ActionHalt
|
||||||
|
}
|
||||||
|
|
||||||
|
target := getTarget(s.OutputDir, s.Name)
|
||||||
|
file, err := os.Create(target)
|
||||||
|
if err != nil {
|
||||||
|
state.Put("error", errors.Wrap(err, "unable to create file: "+target))
|
||||||
|
return multistep.ActionHalt
|
||||||
|
}
|
||||||
|
|
||||||
|
var w io.Writer = file
|
||||||
|
h, ok := s.newHash()
|
||||||
|
if ok {
|
||||||
|
w = io.MultiWriter(file, h)
|
||||||
|
}
|
||||||
|
|
||||||
|
ui.Message("Writing ovf...")
|
||||||
|
_, err = io.WriteString(w, desc.OvfDescriptor)
|
||||||
|
if err != nil {
|
||||||
|
state.Put("error", errors.Wrap(err, "unable to write descriptor"))
|
||||||
|
return multistep.ActionHalt
|
||||||
|
}
|
||||||
|
|
||||||
|
if err = file.Close(); err != nil {
|
||||||
|
state.Put("error", errors.Wrap(err, "unable to close descriptor"))
|
||||||
|
return multistep.ActionHalt
|
||||||
|
}
|
||||||
|
|
||||||
|
if s.Manifest == "none" {
|
||||||
|
// manifest does not need to be created, return
|
||||||
|
return multistep.ActionContinue
|
||||||
|
}
|
||||||
|
|
||||||
|
ui.Message("Creating manifest...")
|
||||||
|
s.addHash(filepath.Base(target), h)
|
||||||
|
|
||||||
|
file, err = os.Create(filepath.Join(s.OutputDir, s.Name+".mf"))
|
||||||
|
if err != nil {
|
||||||
|
state.Put("error", errors.Wrap(err, "unable to create manifest"))
|
||||||
|
return multistep.ActionHalt
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = io.Copy(file, &s.mf)
|
||||||
|
if err != nil {
|
||||||
|
state.Put("error", errors.Wrap(err, "unable to write manifest"))
|
||||||
|
return multistep.ActionHalt
|
||||||
|
}
|
||||||
|
|
||||||
|
err = file.Close()
|
||||||
|
if err != nil {
|
||||||
|
state.Put("error", errors.Wrap(err, "unable to close file"))
|
||||||
|
return multistep.ActionHalt
|
||||||
|
}
|
||||||
|
|
||||||
|
ui.Message("Finished exporting...")
|
||||||
|
return multistep.ActionContinue
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *StepExport) include(item *nfc.FileItem) bool {
|
||||||
|
if s.Images {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
return filepath.Ext(item.Path) == ".vmdk"
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *StepExport) newHash() (hash.Hash, bool) {
|
||||||
|
// check if function is nil to handle the 'none' case
|
||||||
|
if h, ok := sha[s.Manifest]; ok && h != nil {
|
||||||
|
return h(), true
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil, false
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *StepExport) addHash(p string, h hash.Hash) {
|
||||||
|
_, _ = fmt.Fprintf(&s.mf, "%s(%s)= %x\n", strings.ToUpper(s.Manifest), p, h.Sum(nil))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *StepExport) Download(ctx context.Context, lease *nfc.Lease, item nfc.FileItem) error {
|
||||||
|
path := filepath.Join(s.OutputDir, item.Path)
|
||||||
|
opts := soap.Download{}
|
||||||
|
|
||||||
|
if h, ok := s.newHash(); ok {
|
||||||
|
opts.Writer = h
|
||||||
|
defer s.addHash(item.Path, h)
|
||||||
|
}
|
||||||
|
|
||||||
|
return lease.DownloadFile(ctx, path, item, opts)
|
||||||
|
}
|
|
@ -0,0 +1,40 @@
|
||||||
|
// Code generated by "mapstructure-to-hcl2 -type ExportConfig"; DO NOT EDIT.
|
||||||
|
package common
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/hashicorp/hcl/v2/hcldec"
|
||||||
|
"github.com/zclconf/go-cty/cty"
|
||||||
|
)
|
||||||
|
|
||||||
|
// FlatExportConfig is an auto-generated flat version of ExportConfig.
|
||||||
|
// Where the contents of a field with a `mapstructure:,squash` tag are bubbled up.
|
||||||
|
type FlatExportConfig struct {
|
||||||
|
Name *string `mapstructure:"name" cty:"name"`
|
||||||
|
Force *bool `mapstructure:"force" cty:"force"`
|
||||||
|
Images *bool `mapstructure:"images" cty:"images"`
|
||||||
|
Manifest *string `mapstructure:"manifest" cty:"manifest"`
|
||||||
|
OutputDir *string `mapstructure:"output_directory" required:"false" cty:"output_directory"`
|
||||||
|
Options []string `mapstructure:"options" cty:"options"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// FlatMapstructure returns a new FlatExportConfig.
|
||||||
|
// FlatExportConfig is an auto-generated flat version of ExportConfig.
|
||||||
|
// Where the contents a fields with a `mapstructure:,squash` tag are bubbled up.
|
||||||
|
func (*ExportConfig) FlatMapstructure() interface{ HCL2Spec() map[string]hcldec.Spec } {
|
||||||
|
return new(FlatExportConfig)
|
||||||
|
}
|
||||||
|
|
||||||
|
// HCL2Spec returns the hcl spec of a ExportConfig.
|
||||||
|
// This spec is used by HCL to read the fields of ExportConfig.
|
||||||
|
// The decoded values from this spec will then be applied to a FlatExportConfig.
|
||||||
|
func (*FlatExportConfig) HCL2Spec() map[string]hcldec.Spec {
|
||||||
|
s := map[string]hcldec.Spec{
|
||||||
|
"name": &hcldec.AttrSpec{Name: "name", Type: cty.String, Required: false},
|
||||||
|
"force": &hcldec.AttrSpec{Name: "force", Type: cty.Bool, Required: false},
|
||||||
|
"images": &hcldec.AttrSpec{Name: "images", Type: cty.Bool, Required: false},
|
||||||
|
"manifest": &hcldec.AttrSpec{Name: "manifest", Type: cty.String, Required: false},
|
||||||
|
"output_directory": &hcldec.AttrSpec{Name: "output_directory", Type: cty.String, Required: false},
|
||||||
|
"options": &hcldec.AttrSpec{Name: "options", Type: cty.List(cty.String), Required: false},
|
||||||
|
}
|
||||||
|
return s
|
||||||
|
}
|
|
@ -8,6 +8,11 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/vmware/govmomi/property"
|
||||||
|
|
||||||
|
"github.com/vmware/govmomi/nfc"
|
||||||
|
"github.com/vmware/govmomi/ovf"
|
||||||
|
|
||||||
"github.com/vmware/govmomi/object"
|
"github.com/vmware/govmomi/object"
|
||||||
"github.com/vmware/govmomi/vim25/mo"
|
"github.com/vmware/govmomi/vim25/mo"
|
||||||
"github.com/vmware/govmomi/vim25/types"
|
"github.com/vmware/govmomi/vim25/types"
|
||||||
|
@ -688,6 +693,27 @@ func (vm *VirtualMachine) AddConfigParams(params map[string]string) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (vm *VirtualMachine) Export() (*nfc.Lease, error) {
|
||||||
|
return vm.vm.Export(vm.driver.ctx)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (vm *VirtualMachine) CreateDescriptor(m *ovf.Manager, cdp types.OvfCreateDescriptorParams) (*types.OvfCreateDescriptorResult, error) {
|
||||||
|
return m.CreateDescriptor(vm.driver.ctx, vm.vm, cdp)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (vm *VirtualMachine) NewOvfManager() *ovf.Manager {
|
||||||
|
return ovf.NewManager(vm.vm.Client())
|
||||||
|
}
|
||||||
|
|
||||||
|
func (vm *VirtualMachine) GetOvfExportOptions(m *ovf.Manager) ([]types.OvfOptionInfo, error) {
|
||||||
|
var mgr mo.OvfManager
|
||||||
|
err := property.DefaultCollector(vm.vm.Client()).RetrieveOne(vm.driver.ctx, m.Reference(), nil, &mgr)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return mgr.OvfExportOption, nil
|
||||||
|
}
|
||||||
|
|
||||||
func findNetworkAdapter(l object.VirtualDeviceList) (types.BaseVirtualEthernetCard, error) {
|
func findNetworkAdapter(l object.VirtualDeviceList) (types.BaseVirtualEthernetCard, error) {
|
||||||
c := l.SelectByType((*types.VirtualEthernetCard)(nil))
|
c := l.SelectByType((*types.VirtualEthernetCard)(nil))
|
||||||
if len(c) == 0 {
|
if len(c) == 0 {
|
||||||
|
|
|
@ -132,6 +132,16 @@ func (b *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (pack
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if b.config.Export != nil {
|
||||||
|
steps = append(steps, &common.StepExport{
|
||||||
|
Name: b.config.Export.Name,
|
||||||
|
Force: b.config.Export.Force,
|
||||||
|
Images: b.config.Export.Images,
|
||||||
|
Manifest: b.config.Export.Manifest,
|
||||||
|
OutputDir: b.config.Export.OutputDir.OutputDir,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
b.runner = packerCommon.NewRunner(steps, b.config.PackerConfig, ui)
|
b.runner = packerCommon.NewRunner(steps, b.config.PackerConfig, ui)
|
||||||
b.runner.Run(ctx, state)
|
b.runner.Run(ctx, state)
|
||||||
|
|
||||||
|
|
|
@ -39,6 +39,9 @@ type Config struct {
|
||||||
CreateSnapshot bool `mapstructure:"create_snapshot"`
|
CreateSnapshot bool `mapstructure:"create_snapshot"`
|
||||||
// Convert VM to a template. Defaults to `false`.
|
// Convert VM to a template. Defaults to `false`.
|
||||||
ConvertToTemplate bool `mapstructure:"convert_to_template"`
|
ConvertToTemplate bool `mapstructure:"convert_to_template"`
|
||||||
|
// Configuration for exporting VM to an ovf file.
|
||||||
|
// The VM will not be exported if no [Export Configuration](#export-configuration) is specified.
|
||||||
|
Export *common.ExportConfig `mapstructure:"export"`
|
||||||
|
|
||||||
ctx interpolate.Context
|
ctx interpolate.Context
|
||||||
}
|
}
|
||||||
|
@ -77,6 +80,9 @@ func (c *Config) Prepare(raws ...interface{}) ([]string, error) {
|
||||||
errs = packer.MultiErrorAppend(errs, c.WaitIpConfig.Prepare()...)
|
errs = packer.MultiErrorAppend(errs, c.WaitIpConfig.Prepare()...)
|
||||||
errs = packer.MultiErrorAppend(errs, c.Comm.Prepare(&c.ctx)...)
|
errs = packer.MultiErrorAppend(errs, c.Comm.Prepare(&c.ctx)...)
|
||||||
errs = packer.MultiErrorAppend(errs, c.ShutdownConfig.Prepare()...)
|
errs = packer.MultiErrorAppend(errs, c.ShutdownConfig.Prepare()...)
|
||||||
|
if c.Export != nil {
|
||||||
|
errs = packer.MultiErrorAppend(errs, c.Export.Prepare(&c.ctx, &c.LocationConfig, &c.PackerConfig)...)
|
||||||
|
}
|
||||||
|
|
||||||
if len(errs.Errors) > 0 {
|
if len(errs.Errors) > 0 {
|
||||||
return warnings, errs
|
return warnings, errs
|
||||||
|
|
|
@ -3,122 +3,124 @@ package iso
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/hashicorp/hcl/v2/hcldec"
|
"github.com/hashicorp/hcl/v2/hcldec"
|
||||||
|
"github.com/hashicorp/packer/builder/vsphere/common"
|
||||||
"github.com/zclconf/go-cty/cty"
|
"github.com/zclconf/go-cty/cty"
|
||||||
)
|
)
|
||||||
|
|
||||||
// FlatConfig is an auto-generated flat version of Config.
|
// FlatConfig is an auto-generated flat version of Config.
|
||||||
// Where the contents of a field with a `mapstructure:,squash` tag are bubbled up.
|
// Where the contents of a field with a `mapstructure:,squash` tag are bubbled up.
|
||||||
type FlatConfig struct {
|
type FlatConfig struct {
|
||||||
PackerBuildName *string `mapstructure:"packer_build_name" cty:"packer_build_name"`
|
PackerBuildName *string `mapstructure:"packer_build_name" cty:"packer_build_name"`
|
||||||
PackerBuilderType *string `mapstructure:"packer_builder_type" cty:"packer_builder_type"`
|
PackerBuilderType *string `mapstructure:"packer_builder_type" cty:"packer_builder_type"`
|
||||||
PackerDebug *bool `mapstructure:"packer_debug" cty:"packer_debug"`
|
PackerDebug *bool `mapstructure:"packer_debug" cty:"packer_debug"`
|
||||||
PackerForce *bool `mapstructure:"packer_force" cty:"packer_force"`
|
PackerForce *bool `mapstructure:"packer_force" cty:"packer_force"`
|
||||||
PackerOnError *string `mapstructure:"packer_on_error" cty:"packer_on_error"`
|
PackerOnError *string `mapstructure:"packer_on_error" cty:"packer_on_error"`
|
||||||
PackerUserVars map[string]string `mapstructure:"packer_user_variables" cty:"packer_user_variables"`
|
PackerUserVars map[string]string `mapstructure:"packer_user_variables" cty:"packer_user_variables"`
|
||||||
PackerSensitiveVars []string `mapstructure:"packer_sensitive_variables" cty:"packer_sensitive_variables"`
|
PackerSensitiveVars []string `mapstructure:"packer_sensitive_variables" cty:"packer_sensitive_variables"`
|
||||||
HTTPDir *string `mapstructure:"http_directory" cty:"http_directory"`
|
HTTPDir *string `mapstructure:"http_directory" cty:"http_directory"`
|
||||||
HTTPPortMin *int `mapstructure:"http_port_min" cty:"http_port_min"`
|
HTTPPortMin *int `mapstructure:"http_port_min" cty:"http_port_min"`
|
||||||
HTTPPortMax *int `mapstructure:"http_port_max" cty:"http_port_max"`
|
HTTPPortMax *int `mapstructure:"http_port_max" cty:"http_port_max"`
|
||||||
VCenterServer *string `mapstructure:"vcenter_server" cty:"vcenter_server"`
|
VCenterServer *string `mapstructure:"vcenter_server" cty:"vcenter_server"`
|
||||||
Username *string `mapstructure:"username" cty:"username"`
|
Username *string `mapstructure:"username" cty:"username"`
|
||||||
Password *string `mapstructure:"password" cty:"password"`
|
Password *string `mapstructure:"password" cty:"password"`
|
||||||
InsecureConnection *bool `mapstructure:"insecure_connection" cty:"insecure_connection"`
|
InsecureConnection *bool `mapstructure:"insecure_connection" cty:"insecure_connection"`
|
||||||
Datacenter *string `mapstructure:"datacenter" cty:"datacenter"`
|
Datacenter *string `mapstructure:"datacenter" cty:"datacenter"`
|
||||||
Version *uint `mapstructure:"vm_version" cty:"vm_version"`
|
Version *uint `mapstructure:"vm_version" cty:"vm_version"`
|
||||||
GuestOSType *string `mapstructure:"guest_os_type" cty:"guest_os_type"`
|
GuestOSType *string `mapstructure:"guest_os_type" cty:"guest_os_type"`
|
||||||
Firmware *string `mapstructure:"firmware" cty:"firmware"`
|
Firmware *string `mapstructure:"firmware" cty:"firmware"`
|
||||||
DiskControllerType *string `mapstructure:"disk_controller_type" cty:"disk_controller_type"`
|
DiskControllerType *string `mapstructure:"disk_controller_type" cty:"disk_controller_type"`
|
||||||
DiskSize *int64 `mapstructure:"disk_size" cty:"disk_size"`
|
DiskSize *int64 `mapstructure:"disk_size" cty:"disk_size"`
|
||||||
DiskThinProvisioned *bool `mapstructure:"disk_thin_provisioned" cty:"disk_thin_provisioned"`
|
DiskThinProvisioned *bool `mapstructure:"disk_thin_provisioned" cty:"disk_thin_provisioned"`
|
||||||
DiskEagerlyScrub *bool `mapstructure:"disk_eagerly_scrub" cty:"disk_eagerly_scrub"`
|
DiskEagerlyScrub *bool `mapstructure:"disk_eagerly_scrub" cty:"disk_eagerly_scrub"`
|
||||||
Storage []FlatDiskConfig `mapstructure:"storage" cty:"storage"`
|
Storage []FlatDiskConfig `mapstructure:"storage" cty:"storage"`
|
||||||
Network *string `mapstructure:"network" cty:"network"`
|
Network *string `mapstructure:"network" cty:"network"`
|
||||||
NetworkCard *string `mapstructure:"network_card" cty:"network_card"`
|
NetworkCard *string `mapstructure:"network_card" cty:"network_card"`
|
||||||
NICs []FlatNIC `mapstructure:"network_adapters" cty:"network_adapters"`
|
NICs []FlatNIC `mapstructure:"network_adapters" cty:"network_adapters"`
|
||||||
USBController *bool `mapstructure:"usb_controller" cty:"usb_controller"`
|
USBController *bool `mapstructure:"usb_controller" cty:"usb_controller"`
|
||||||
Notes *string `mapstructure:"notes" cty:"notes"`
|
Notes *string `mapstructure:"notes" cty:"notes"`
|
||||||
VMName *string `mapstructure:"vm_name" cty:"vm_name"`
|
VMName *string `mapstructure:"vm_name" cty:"vm_name"`
|
||||||
Folder *string `mapstructure:"folder" cty:"folder"`
|
Folder *string `mapstructure:"folder" cty:"folder"`
|
||||||
Cluster *string `mapstructure:"cluster" cty:"cluster"`
|
Cluster *string `mapstructure:"cluster" cty:"cluster"`
|
||||||
Host *string `mapstructure:"host" cty:"host"`
|
Host *string `mapstructure:"host" cty:"host"`
|
||||||
ResourcePool *string `mapstructure:"resource_pool" cty:"resource_pool"`
|
ResourcePool *string `mapstructure:"resource_pool" cty:"resource_pool"`
|
||||||
Datastore *string `mapstructure:"datastore" cty:"datastore"`
|
Datastore *string `mapstructure:"datastore" cty:"datastore"`
|
||||||
CPUs *int32 `mapstructure:"CPUs" cty:"CPUs"`
|
CPUs *int32 `mapstructure:"CPUs" cty:"CPUs"`
|
||||||
CpuCores *int32 `mapstructure:"cpu_cores" cty:"cpu_cores"`
|
CpuCores *int32 `mapstructure:"cpu_cores" cty:"cpu_cores"`
|
||||||
CPUReservation *int64 `mapstructure:"CPU_reservation" cty:"CPU_reservation"`
|
CPUReservation *int64 `mapstructure:"CPU_reservation" cty:"CPU_reservation"`
|
||||||
CPULimit *int64 `mapstructure:"CPU_limit" cty:"CPU_limit"`
|
CPULimit *int64 `mapstructure:"CPU_limit" cty:"CPU_limit"`
|
||||||
CpuHotAddEnabled *bool `mapstructure:"CPU_hot_plug" cty:"CPU_hot_plug"`
|
CpuHotAddEnabled *bool `mapstructure:"CPU_hot_plug" cty:"CPU_hot_plug"`
|
||||||
RAM *int64 `mapstructure:"RAM" cty:"RAM"`
|
RAM *int64 `mapstructure:"RAM" cty:"RAM"`
|
||||||
RAMReservation *int64 `mapstructure:"RAM_reservation" cty:"RAM_reservation"`
|
RAMReservation *int64 `mapstructure:"RAM_reservation" cty:"RAM_reservation"`
|
||||||
RAMReserveAll *bool `mapstructure:"RAM_reserve_all" cty:"RAM_reserve_all"`
|
RAMReserveAll *bool `mapstructure:"RAM_reserve_all" cty:"RAM_reserve_all"`
|
||||||
MemoryHotAddEnabled *bool `mapstructure:"RAM_hot_plug" cty:"RAM_hot_plug"`
|
MemoryHotAddEnabled *bool `mapstructure:"RAM_hot_plug" cty:"RAM_hot_plug"`
|
||||||
VideoRAM *int64 `mapstructure:"video_ram" cty:"video_ram"`
|
VideoRAM *int64 `mapstructure:"video_ram" cty:"video_ram"`
|
||||||
NestedHV *bool `mapstructure:"NestedHV" cty:"NestedHV"`
|
NestedHV *bool `mapstructure:"NestedHV" cty:"NestedHV"`
|
||||||
ConfigParams map[string]string `mapstructure:"configuration_parameters" cty:"configuration_parameters"`
|
ConfigParams map[string]string `mapstructure:"configuration_parameters" cty:"configuration_parameters"`
|
||||||
ISOChecksum *string `mapstructure:"iso_checksum" required:"true" cty:"iso_checksum"`
|
ISOChecksum *string `mapstructure:"iso_checksum" required:"true" cty:"iso_checksum"`
|
||||||
ISOChecksumURL *string `mapstructure:"iso_checksum_url" cty:"iso_checksum_url"`
|
ISOChecksumURL *string `mapstructure:"iso_checksum_url" cty:"iso_checksum_url"`
|
||||||
ISOChecksumType *string `mapstructure:"iso_checksum_type" cty:"iso_checksum_type"`
|
ISOChecksumType *string `mapstructure:"iso_checksum_type" cty:"iso_checksum_type"`
|
||||||
RawSingleISOUrl *string `mapstructure:"iso_url" required:"true" cty:"iso_url"`
|
RawSingleISOUrl *string `mapstructure:"iso_url" required:"true" cty:"iso_url"`
|
||||||
ISOUrls []string `mapstructure:"iso_urls" cty:"iso_urls"`
|
ISOUrls []string `mapstructure:"iso_urls" cty:"iso_urls"`
|
||||||
TargetPath *string `mapstructure:"iso_target_path" cty:"iso_target_path"`
|
TargetPath *string `mapstructure:"iso_target_path" cty:"iso_target_path"`
|
||||||
TargetExtension *string `mapstructure:"iso_target_extension" cty:"iso_target_extension"`
|
TargetExtension *string `mapstructure:"iso_target_extension" cty:"iso_target_extension"`
|
||||||
CdromType *string `mapstructure:"cdrom_type" cty:"cdrom_type"`
|
CdromType *string `mapstructure:"cdrom_type" cty:"cdrom_type"`
|
||||||
ISOPaths []string `mapstructure:"iso_paths" cty:"iso_paths"`
|
ISOPaths []string `mapstructure:"iso_paths" cty:"iso_paths"`
|
||||||
RemoveCdrom *bool `mapstructure:"remove_cdrom" cty:"remove_cdrom"`
|
RemoveCdrom *bool `mapstructure:"remove_cdrom" cty:"remove_cdrom"`
|
||||||
FloppyIMGPath *string `mapstructure:"floppy_img_path" cty:"floppy_img_path"`
|
FloppyIMGPath *string `mapstructure:"floppy_img_path" cty:"floppy_img_path"`
|
||||||
FloppyFiles []string `mapstructure:"floppy_files" cty:"floppy_files"`
|
FloppyFiles []string `mapstructure:"floppy_files" cty:"floppy_files"`
|
||||||
FloppyDirectories []string `mapstructure:"floppy_dirs" cty:"floppy_dirs"`
|
FloppyDirectories []string `mapstructure:"floppy_dirs" cty:"floppy_dirs"`
|
||||||
BootOrder *string `mapstructure:"boot_order" cty:"boot_order"`
|
BootOrder *string `mapstructure:"boot_order" cty:"boot_order"`
|
||||||
BootCommand []string `mapstructure:"boot_command" cty:"boot_command"`
|
BootCommand []string `mapstructure:"boot_command" cty:"boot_command"`
|
||||||
BootWait *string `mapstructure:"boot_wait" cty:"boot_wait"`
|
BootWait *string `mapstructure:"boot_wait" cty:"boot_wait"`
|
||||||
HTTPIP *string `mapstructure:"http_ip" cty:"http_ip"`
|
HTTPIP *string `mapstructure:"http_ip" cty:"http_ip"`
|
||||||
WaitTimeout *string `mapstructure:"ip_wait_timeout" cty:"ip_wait_timeout"`
|
WaitTimeout *string `mapstructure:"ip_wait_timeout" cty:"ip_wait_timeout"`
|
||||||
SettleTimeout *string `mapstructure:"ip_settle_timeout" cty:"ip_settle_timeout"`
|
SettleTimeout *string `mapstructure:"ip_settle_timeout" cty:"ip_settle_timeout"`
|
||||||
Type *string `mapstructure:"communicator" cty:"communicator"`
|
Type *string `mapstructure:"communicator" cty:"communicator"`
|
||||||
PauseBeforeConnect *string `mapstructure:"pause_before_connecting" cty:"pause_before_connecting"`
|
PauseBeforeConnect *string `mapstructure:"pause_before_connecting" cty:"pause_before_connecting"`
|
||||||
SSHHost *string `mapstructure:"ssh_host" cty:"ssh_host"`
|
SSHHost *string `mapstructure:"ssh_host" cty:"ssh_host"`
|
||||||
SSHPort *int `mapstructure:"ssh_port" cty:"ssh_port"`
|
SSHPort *int `mapstructure:"ssh_port" cty:"ssh_port"`
|
||||||
SSHUsername *string `mapstructure:"ssh_username" cty:"ssh_username"`
|
SSHUsername *string `mapstructure:"ssh_username" cty:"ssh_username"`
|
||||||
SSHPassword *string `mapstructure:"ssh_password" cty:"ssh_password"`
|
SSHPassword *string `mapstructure:"ssh_password" cty:"ssh_password"`
|
||||||
SSHKeyPairName *string `mapstructure:"ssh_keypair_name" cty:"ssh_keypair_name"`
|
SSHKeyPairName *string `mapstructure:"ssh_keypair_name" cty:"ssh_keypair_name"`
|
||||||
SSHTemporaryKeyPairName *string `mapstructure:"temporary_key_pair_name" cty:"temporary_key_pair_name"`
|
SSHTemporaryKeyPairName *string `mapstructure:"temporary_key_pair_name" cty:"temporary_key_pair_name"`
|
||||||
SSHClearAuthorizedKeys *bool `mapstructure:"ssh_clear_authorized_keys" cty:"ssh_clear_authorized_keys"`
|
SSHClearAuthorizedKeys *bool `mapstructure:"ssh_clear_authorized_keys" cty:"ssh_clear_authorized_keys"`
|
||||||
SSHPrivateKeyFile *string `mapstructure:"ssh_private_key_file" cty:"ssh_private_key_file"`
|
SSHPrivateKeyFile *string `mapstructure:"ssh_private_key_file" cty:"ssh_private_key_file"`
|
||||||
SSHPty *bool `mapstructure:"ssh_pty" cty:"ssh_pty"`
|
SSHPty *bool `mapstructure:"ssh_pty" cty:"ssh_pty"`
|
||||||
SSHTimeout *string `mapstructure:"ssh_timeout" cty:"ssh_timeout"`
|
SSHTimeout *string `mapstructure:"ssh_timeout" cty:"ssh_timeout"`
|
||||||
SSHAgentAuth *bool `mapstructure:"ssh_agent_auth" cty:"ssh_agent_auth"`
|
SSHAgentAuth *bool `mapstructure:"ssh_agent_auth" cty:"ssh_agent_auth"`
|
||||||
SSHDisableAgentForwarding *bool `mapstructure:"ssh_disable_agent_forwarding" cty:"ssh_disable_agent_forwarding"`
|
SSHDisableAgentForwarding *bool `mapstructure:"ssh_disable_agent_forwarding" cty:"ssh_disable_agent_forwarding"`
|
||||||
SSHHandshakeAttempts *int `mapstructure:"ssh_handshake_attempts" cty:"ssh_handshake_attempts"`
|
SSHHandshakeAttempts *int `mapstructure:"ssh_handshake_attempts" cty:"ssh_handshake_attempts"`
|
||||||
SSHBastionHost *string `mapstructure:"ssh_bastion_host" cty:"ssh_bastion_host"`
|
SSHBastionHost *string `mapstructure:"ssh_bastion_host" cty:"ssh_bastion_host"`
|
||||||
SSHBastionPort *int `mapstructure:"ssh_bastion_port" cty:"ssh_bastion_port"`
|
SSHBastionPort *int `mapstructure:"ssh_bastion_port" cty:"ssh_bastion_port"`
|
||||||
SSHBastionAgentAuth *bool `mapstructure:"ssh_bastion_agent_auth" cty:"ssh_bastion_agent_auth"`
|
SSHBastionAgentAuth *bool `mapstructure:"ssh_bastion_agent_auth" cty:"ssh_bastion_agent_auth"`
|
||||||
SSHBastionUsername *string `mapstructure:"ssh_bastion_username" cty:"ssh_bastion_username"`
|
SSHBastionUsername *string `mapstructure:"ssh_bastion_username" cty:"ssh_bastion_username"`
|
||||||
SSHBastionPassword *string `mapstructure:"ssh_bastion_password" cty:"ssh_bastion_password"`
|
SSHBastionPassword *string `mapstructure:"ssh_bastion_password" cty:"ssh_bastion_password"`
|
||||||
SSHBastionInteractive *bool `mapstructure:"ssh_bastion_interactive" cty:"ssh_bastion_interactive"`
|
SSHBastionInteractive *bool `mapstructure:"ssh_bastion_interactive" cty:"ssh_bastion_interactive"`
|
||||||
SSHBastionPrivateKeyFile *string `mapstructure:"ssh_bastion_private_key_file" cty:"ssh_bastion_private_key_file"`
|
SSHBastionPrivateKeyFile *string `mapstructure:"ssh_bastion_private_key_file" cty:"ssh_bastion_private_key_file"`
|
||||||
SSHFileTransferMethod *string `mapstructure:"ssh_file_transfer_method" cty:"ssh_file_transfer_method"`
|
SSHFileTransferMethod *string `mapstructure:"ssh_file_transfer_method" cty:"ssh_file_transfer_method"`
|
||||||
SSHProxyHost *string `mapstructure:"ssh_proxy_host" cty:"ssh_proxy_host"`
|
SSHProxyHost *string `mapstructure:"ssh_proxy_host" cty:"ssh_proxy_host"`
|
||||||
SSHProxyPort *int `mapstructure:"ssh_proxy_port" cty:"ssh_proxy_port"`
|
SSHProxyPort *int `mapstructure:"ssh_proxy_port" cty:"ssh_proxy_port"`
|
||||||
SSHProxyUsername *string `mapstructure:"ssh_proxy_username" cty:"ssh_proxy_username"`
|
SSHProxyUsername *string `mapstructure:"ssh_proxy_username" cty:"ssh_proxy_username"`
|
||||||
SSHProxyPassword *string `mapstructure:"ssh_proxy_password" cty:"ssh_proxy_password"`
|
SSHProxyPassword *string `mapstructure:"ssh_proxy_password" cty:"ssh_proxy_password"`
|
||||||
SSHKeepAliveInterval *string `mapstructure:"ssh_keep_alive_interval" cty:"ssh_keep_alive_interval"`
|
SSHKeepAliveInterval *string `mapstructure:"ssh_keep_alive_interval" cty:"ssh_keep_alive_interval"`
|
||||||
SSHReadWriteTimeout *string `mapstructure:"ssh_read_write_timeout" cty:"ssh_read_write_timeout"`
|
SSHReadWriteTimeout *string `mapstructure:"ssh_read_write_timeout" cty:"ssh_read_write_timeout"`
|
||||||
SSHRemoteTunnels []string `mapstructure:"ssh_remote_tunnels" cty:"ssh_remote_tunnels"`
|
SSHRemoteTunnels []string `mapstructure:"ssh_remote_tunnels" cty:"ssh_remote_tunnels"`
|
||||||
SSHLocalTunnels []string `mapstructure:"ssh_local_tunnels" cty:"ssh_local_tunnels"`
|
SSHLocalTunnels []string `mapstructure:"ssh_local_tunnels" cty:"ssh_local_tunnels"`
|
||||||
SSHPublicKey []byte `mapstructure:"ssh_public_key" cty:"ssh_public_key"`
|
SSHPublicKey []byte `mapstructure:"ssh_public_key" cty:"ssh_public_key"`
|
||||||
SSHPrivateKey []byte `mapstructure:"ssh_private_key" cty:"ssh_private_key"`
|
SSHPrivateKey []byte `mapstructure:"ssh_private_key" cty:"ssh_private_key"`
|
||||||
WinRMUser *string `mapstructure:"winrm_username" cty:"winrm_username"`
|
WinRMUser *string `mapstructure:"winrm_username" cty:"winrm_username"`
|
||||||
WinRMPassword *string `mapstructure:"winrm_password" cty:"winrm_password"`
|
WinRMPassword *string `mapstructure:"winrm_password" cty:"winrm_password"`
|
||||||
WinRMHost *string `mapstructure:"winrm_host" cty:"winrm_host"`
|
WinRMHost *string `mapstructure:"winrm_host" cty:"winrm_host"`
|
||||||
WinRMPort *int `mapstructure:"winrm_port" cty:"winrm_port"`
|
WinRMPort *int `mapstructure:"winrm_port" cty:"winrm_port"`
|
||||||
WinRMTimeout *string `mapstructure:"winrm_timeout" cty:"winrm_timeout"`
|
WinRMTimeout *string `mapstructure:"winrm_timeout" cty:"winrm_timeout"`
|
||||||
WinRMUseSSL *bool `mapstructure:"winrm_use_ssl" cty:"winrm_use_ssl"`
|
WinRMUseSSL *bool `mapstructure:"winrm_use_ssl" cty:"winrm_use_ssl"`
|
||||||
WinRMInsecure *bool `mapstructure:"winrm_insecure" cty:"winrm_insecure"`
|
WinRMInsecure *bool `mapstructure:"winrm_insecure" cty:"winrm_insecure"`
|
||||||
WinRMUseNTLM *bool `mapstructure:"winrm_use_ntlm" cty:"winrm_use_ntlm"`
|
WinRMUseNTLM *bool `mapstructure:"winrm_use_ntlm" cty:"winrm_use_ntlm"`
|
||||||
Command *string `mapstructure:"shutdown_command" cty:"shutdown_command"`
|
Command *string `mapstructure:"shutdown_command" cty:"shutdown_command"`
|
||||||
Timeout *string `mapstructure:"shutdown_timeout" cty:"shutdown_timeout"`
|
Timeout *string `mapstructure:"shutdown_timeout" cty:"shutdown_timeout"`
|
||||||
CreateSnapshot *bool `mapstructure:"create_snapshot" cty:"create_snapshot"`
|
CreateSnapshot *bool `mapstructure:"create_snapshot" cty:"create_snapshot"`
|
||||||
ConvertToTemplate *bool `mapstructure:"convert_to_template" cty:"convert_to_template"`
|
ConvertToTemplate *bool `mapstructure:"convert_to_template" cty:"convert_to_template"`
|
||||||
|
Export *common.FlatExportConfig `mapstructure:"export" cty:"export"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// FlatMapstructure returns a new FlatConfig.
|
// FlatMapstructure returns a new FlatConfig.
|
||||||
|
@ -243,6 +245,7 @@ func (*FlatConfig) HCL2Spec() map[string]hcldec.Spec {
|
||||||
"shutdown_timeout": &hcldec.AttrSpec{Name: "shutdown_timeout", Type: cty.String, Required: false},
|
"shutdown_timeout": &hcldec.AttrSpec{Name: "shutdown_timeout", Type: cty.String, Required: false},
|
||||||
"create_snapshot": &hcldec.AttrSpec{Name: "create_snapshot", Type: cty.Bool, Required: false},
|
"create_snapshot": &hcldec.AttrSpec{Name: "create_snapshot", Type: cty.Bool, Required: false},
|
||||||
"convert_to_template": &hcldec.AttrSpec{Name: "convert_to_template", Type: cty.Bool, Required: false},
|
"convert_to_template": &hcldec.AttrSpec{Name: "convert_to_template", Type: cty.Bool, Required: false},
|
||||||
|
"export": &hcldec.BlockSpec{TypeName: "export", Nested: hcldec.ObjectSpec((*common.FlatExportConfig)(nil).HCL2Spec())},
|
||||||
}
|
}
|
||||||
return s
|
return s
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,78 @@
|
||||||
|
/*
|
||||||
|
Copyright (c) 2015 VMware, Inc. All Rights Reserved.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package ovf
|
||||||
|
|
||||||
|
/*
|
||||||
|
Source: http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2.24.0/CIM_VirtualSystemSettingData.xsd
|
||||||
|
*/
|
||||||
|
|
||||||
|
type CIMVirtualSystemSettingData struct {
|
||||||
|
ElementName string `xml:"ElementName"`
|
||||||
|
InstanceID string `xml:"InstanceID"`
|
||||||
|
|
||||||
|
AutomaticRecoveryAction *uint8 `xml:"AutomaticRecoveryAction"`
|
||||||
|
AutomaticShutdownAction *uint8 `xml:"AutomaticShutdownAction"`
|
||||||
|
AutomaticStartupAction *uint8 `xml:"AutomaticStartupAction"`
|
||||||
|
AutomaticStartupActionDelay *string `xml:"AutomaticStartupActionDelay>Interval"`
|
||||||
|
AutomaticStartupActionSequenceNumber *uint16 `xml:"AutomaticStartupActionSequenceNumber"`
|
||||||
|
Caption *string `xml:"Caption"`
|
||||||
|
ConfigurationDataRoot *string `xml:"ConfigurationDataRoot"`
|
||||||
|
ConfigurationFile *string `xml:"ConfigurationFile"`
|
||||||
|
ConfigurationID *string `xml:"ConfigurationID"`
|
||||||
|
CreationTime *string `xml:"CreationTime"`
|
||||||
|
Description *string `xml:"Description"`
|
||||||
|
LogDataRoot *string `xml:"LogDataRoot"`
|
||||||
|
Notes []string `xml:"Notes"`
|
||||||
|
RecoveryFile *string `xml:"RecoveryFile"`
|
||||||
|
SnapshotDataRoot *string `xml:"SnapshotDataRoot"`
|
||||||
|
SuspendDataRoot *string `xml:"SuspendDataRoot"`
|
||||||
|
SwapFileDataRoot *string `xml:"SwapFileDataRoot"`
|
||||||
|
VirtualSystemIdentifier *string `xml:"VirtualSystemIdentifier"`
|
||||||
|
VirtualSystemType *string `xml:"VirtualSystemType"`
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Source: http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2.24.0/CIM_ResourceAllocationSettingData.xsd
|
||||||
|
*/
|
||||||
|
|
||||||
|
type CIMResourceAllocationSettingData struct {
|
||||||
|
ElementName string `xml:"ElementName"`
|
||||||
|
InstanceID string `xml:"InstanceID"`
|
||||||
|
|
||||||
|
ResourceType *uint16 `xml:"ResourceType"`
|
||||||
|
OtherResourceType *string `xml:"OtherResourceType"`
|
||||||
|
ResourceSubType *string `xml:"ResourceSubType"`
|
||||||
|
|
||||||
|
AddressOnParent *string `xml:"AddressOnParent"`
|
||||||
|
Address *string `xml:"Address"`
|
||||||
|
AllocationUnits *string `xml:"AllocationUnits"`
|
||||||
|
AutomaticAllocation *bool `xml:"AutomaticAllocation"`
|
||||||
|
AutomaticDeallocation *bool `xml:"AutomaticDeallocation"`
|
||||||
|
Caption *string `xml:"Caption"`
|
||||||
|
Connection []string `xml:"Connection"`
|
||||||
|
ConsumerVisibility *uint16 `xml:"ConsumerVisibility"`
|
||||||
|
Description *string `xml:"Description"`
|
||||||
|
HostResource []string `xml:"HostResource"`
|
||||||
|
Limit *uint64 `xml:"Limit"`
|
||||||
|
MappingBehavior *uint `xml:"MappingBehavior"`
|
||||||
|
Parent *string `xml:"Parent"`
|
||||||
|
PoolID *string `xml:"PoolID"`
|
||||||
|
Reservation *uint64 `xml:"Reservation"`
|
||||||
|
VirtualQuantity *uint `xml:"VirtualQuantity"`
|
||||||
|
VirtualQuantityUnits *string `xml:"VirtualQuantityUnits"`
|
||||||
|
Weight *uint `xml:"Weight"`
|
||||||
|
}
|
|
@ -0,0 +1,25 @@
|
||||||
|
/*
|
||||||
|
Copyright (c) 2015 VMware, Inc. All Rights Reserved.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
Package ovf provides functionality to unmarshal and inspect the structure
|
||||||
|
of an OVF file. It is not a complete implementation of the specification and
|
||||||
|
is intended to be used to import virtual infrastructure into vSphere.
|
||||||
|
|
||||||
|
For a complete specification of the OVF standard, refer to:
|
||||||
|
https://www.dmtf.org/sites/default/files/standards/documents/DSP0243_2.1.0.pdf
|
||||||
|
*/
|
||||||
|
package ovf
|
|
@ -0,0 +1,99 @@
|
||||||
|
/*
|
||||||
|
Copyright (c) 2015 VMware, Inc. All Rights Reserved.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package ovf
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/vmware/govmomi/vim25/xml"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
ovfEnvHeader = `<Environment
|
||||||
|
xmlns="http://schemas.dmtf.org/ovf/environment/1"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xmlns:oe="http://schemas.dmtf.org/ovf/environment/1"
|
||||||
|
xmlns:ve="http://www.vmware.com/schema/ovfenv"
|
||||||
|
oe:id=""
|
||||||
|
ve:esxId="%s">`
|
||||||
|
ovfEnvPlatformSection = `<PlatformSection>
|
||||||
|
<Kind>%s</Kind>
|
||||||
|
<Version>%s</Version>
|
||||||
|
<Vendor>%s</Vendor>
|
||||||
|
<Locale>%s</Locale>
|
||||||
|
</PlatformSection>`
|
||||||
|
ovfEnvPropertyHeader = `<PropertySection>`
|
||||||
|
ovfEnvPropertyEntry = `<Property oe:key="%s" oe:value="%s"/>`
|
||||||
|
ovfEnvPropertyFooter = `</PropertySection>`
|
||||||
|
ovfEnvFooter = `</Environment>`
|
||||||
|
)
|
||||||
|
|
||||||
|
type Env struct {
|
||||||
|
XMLName xml.Name `xml:"http://schemas.dmtf.org/ovf/environment/1 Environment"`
|
||||||
|
ID string `xml:"id,attr"`
|
||||||
|
EsxID string `xml:"http://www.vmware.com/schema/ovfenv esxId,attr"`
|
||||||
|
|
||||||
|
Platform *PlatformSection `xml:"PlatformSection"`
|
||||||
|
Property *PropertySection `xml:"PropertySection"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type PlatformSection struct {
|
||||||
|
Kind string `xml:"Kind"`
|
||||||
|
Version string `xml:"Version"`
|
||||||
|
Vendor string `xml:"Vendor"`
|
||||||
|
Locale string `xml:"Locale"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type PropertySection struct {
|
||||||
|
Properties []EnvProperty `xml:"Property"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type EnvProperty struct {
|
||||||
|
Key string `xml:"key,attr"`
|
||||||
|
Value string `xml:"value,attr"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Marshal marshals Env to xml by using xml.Marshal.
|
||||||
|
func (e Env) Marshal() (string, error) {
|
||||||
|
x, err := xml.Marshal(e)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
return fmt.Sprintf("%s%s", xml.Header, x), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// MarshalManual manually marshals Env to xml suitable for a vApp guest.
|
||||||
|
// It exists to overcome the lack of expressiveness in Go's XML namespaces.
|
||||||
|
func (e Env) MarshalManual() string {
|
||||||
|
var buffer bytes.Buffer
|
||||||
|
|
||||||
|
buffer.WriteString(xml.Header)
|
||||||
|
buffer.WriteString(fmt.Sprintf(ovfEnvHeader, e.EsxID))
|
||||||
|
buffer.WriteString(fmt.Sprintf(ovfEnvPlatformSection, e.Platform.Kind, e.Platform.Version, e.Platform.Vendor, e.Platform.Locale))
|
||||||
|
|
||||||
|
buffer.WriteString(fmt.Sprint(ovfEnvPropertyHeader))
|
||||||
|
for _, p := range e.Property.Properties {
|
||||||
|
buffer.WriteString(fmt.Sprintf(ovfEnvPropertyEntry, p.Key, p.Value))
|
||||||
|
}
|
||||||
|
buffer.WriteString(fmt.Sprint(ovfEnvPropertyFooter))
|
||||||
|
|
||||||
|
buffer.WriteString(fmt.Sprint(ovfEnvFooter))
|
||||||
|
|
||||||
|
return buffer.String()
|
||||||
|
}
|
|
@ -0,0 +1,191 @@
|
||||||
|
/*
|
||||||
|
Copyright (c) 2015 VMware, Inc. All Rights Reserved.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package ovf
|
||||||
|
|
||||||
|
type Envelope struct {
|
||||||
|
References []File `xml:"References>File"`
|
||||||
|
|
||||||
|
// Package level meta-data
|
||||||
|
Annotation *AnnotationSection `xml:"AnnotationSection"`
|
||||||
|
Product *ProductSection `xml:"ProductSection"`
|
||||||
|
Network *NetworkSection `xml:"NetworkSection"`
|
||||||
|
Disk *DiskSection `xml:"DiskSection"`
|
||||||
|
OperatingSystem *OperatingSystemSection `xml:"OperatingSystemSection"`
|
||||||
|
Eula *EulaSection `xml:"EulaSection"`
|
||||||
|
VirtualHardware *VirtualHardwareSection `xml:"VirtualHardwareSection"`
|
||||||
|
ResourceAllocation *ResourceAllocationSection `xml:"ResourceAllocationSection"`
|
||||||
|
DeploymentOption *DeploymentOptionSection `xml:"DeploymentOptionSection"`
|
||||||
|
|
||||||
|
// Content: A VirtualSystem or a VirtualSystemCollection
|
||||||
|
VirtualSystem *VirtualSystem `xml:"VirtualSystem"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type VirtualSystem struct {
|
||||||
|
Content
|
||||||
|
|
||||||
|
Annotation []AnnotationSection `xml:"AnnotationSection"`
|
||||||
|
Product []ProductSection `xml:"ProductSection"`
|
||||||
|
OperatingSystem []OperatingSystemSection `xml:"OperatingSystemSection"`
|
||||||
|
Eula []EulaSection `xml:"EulaSection"`
|
||||||
|
VirtualHardware []VirtualHardwareSection `xml:"VirtualHardwareSection"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type File struct {
|
||||||
|
ID string `xml:"id,attr"`
|
||||||
|
Href string `xml:"href,attr"`
|
||||||
|
Size uint `xml:"size,attr"`
|
||||||
|
Compression *string `xml:"compression,attr"`
|
||||||
|
ChunkSize *int `xml:"chunkSize,attr"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type Content struct {
|
||||||
|
ID string `xml:"id,attr"`
|
||||||
|
Info string `xml:"Info"`
|
||||||
|
Name *string `xml:"Name"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type Section struct {
|
||||||
|
Required *bool `xml:"required,attr"`
|
||||||
|
Info string `xml:"Info"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type AnnotationSection struct {
|
||||||
|
Section
|
||||||
|
|
||||||
|
Annotation string `xml:"Annotation"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type ProductSection struct {
|
||||||
|
Section
|
||||||
|
|
||||||
|
Class *string `xml:"class,attr"`
|
||||||
|
Instance *string `xml:"instance,attr"`
|
||||||
|
|
||||||
|
Product string `xml:"Product"`
|
||||||
|
Vendor string `xml:"Vendor"`
|
||||||
|
Version string `xml:"Version"`
|
||||||
|
FullVersion string `xml:"FullVersion"`
|
||||||
|
ProductURL string `xml:"ProductUrl"`
|
||||||
|
VendorURL string `xml:"VendorUrl"`
|
||||||
|
AppURL string `xml:"AppUrl"`
|
||||||
|
Property []Property `xml:"Property"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type Property struct {
|
||||||
|
Key string `xml:"key,attr"`
|
||||||
|
Type string `xml:"type,attr"`
|
||||||
|
Qualifiers *string `xml:"qualifiers,attr"`
|
||||||
|
UserConfigurable *bool `xml:"userConfigurable,attr"`
|
||||||
|
Default *string `xml:"value,attr"`
|
||||||
|
Password *bool `xml:"password,attr"`
|
||||||
|
|
||||||
|
Label *string `xml:"Label"`
|
||||||
|
Description *string `xml:"Description"`
|
||||||
|
|
||||||
|
Values []PropertyConfigurationValue `xml:"Value"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type PropertyConfigurationValue struct {
|
||||||
|
Value string `xml:"value,attr"`
|
||||||
|
Configuration *string `xml:"configuration,attr"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type NetworkSection struct {
|
||||||
|
Section
|
||||||
|
|
||||||
|
Networks []Network `xml:"Network"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type Network struct {
|
||||||
|
Name string `xml:"name,attr"`
|
||||||
|
|
||||||
|
Description string `xml:"Description"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type DiskSection struct {
|
||||||
|
Section
|
||||||
|
|
||||||
|
Disks []VirtualDiskDesc `xml:"Disk"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type VirtualDiskDesc struct {
|
||||||
|
DiskID string `xml:"diskId,attr"`
|
||||||
|
FileRef *string `xml:"fileRef,attr"`
|
||||||
|
Capacity string `xml:"capacity,attr"`
|
||||||
|
CapacityAllocationUnits *string `xml:"capacityAllocationUnits,attr"`
|
||||||
|
Format *string `xml:"format,attr"`
|
||||||
|
PopulatedSize *int `xml:"populatedSize,attr"`
|
||||||
|
ParentRef *string `xml:"parentRef,attr"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type OperatingSystemSection struct {
|
||||||
|
Section
|
||||||
|
|
||||||
|
ID int16 `xml:"id,attr"`
|
||||||
|
Version *string `xml:"version,attr"`
|
||||||
|
OSType *string `xml:"osType,attr"`
|
||||||
|
|
||||||
|
Description *string `xml:"Description"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type EulaSection struct {
|
||||||
|
Section
|
||||||
|
|
||||||
|
License string `xml:"License"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type VirtualHardwareSection struct {
|
||||||
|
Section
|
||||||
|
|
||||||
|
ID *string `xml:"id,attr"`
|
||||||
|
Transport *string `xml:"transport,attr"`
|
||||||
|
|
||||||
|
System *VirtualSystemSettingData `xml:"System"`
|
||||||
|
Item []ResourceAllocationSettingData `xml:"Item"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type VirtualSystemSettingData struct {
|
||||||
|
CIMVirtualSystemSettingData
|
||||||
|
}
|
||||||
|
|
||||||
|
type ResourceAllocationSettingData struct {
|
||||||
|
CIMResourceAllocationSettingData
|
||||||
|
|
||||||
|
Required *bool `xml:"required,attr"`
|
||||||
|
Configuration *string `xml:"configuration,attr"`
|
||||||
|
Bound *string `xml:"bound,attr"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type ResourceAllocationSection struct {
|
||||||
|
Section
|
||||||
|
|
||||||
|
Item []ResourceAllocationSettingData `xml:"Item"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type DeploymentOptionSection struct {
|
||||||
|
Section
|
||||||
|
|
||||||
|
Configuration []DeploymentOptionConfiguration `xml:"Configuration"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type DeploymentOptionConfiguration struct {
|
||||||
|
ID string `xml:"id,attr"`
|
||||||
|
Default *bool `xml:"default,attr"`
|
||||||
|
|
||||||
|
Label string `xml:"Label"`
|
||||||
|
Description string `xml:"Description"`
|
||||||
|
}
|
|
@ -0,0 +1,103 @@
|
||||||
|
/*
|
||||||
|
Copyright (c) 2015-2017 VMware, Inc. All Rights Reserved.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package ovf
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
"github.com/vmware/govmomi/vim25"
|
||||||
|
"github.com/vmware/govmomi/vim25/methods"
|
||||||
|
"github.com/vmware/govmomi/vim25/mo"
|
||||||
|
"github.com/vmware/govmomi/vim25/types"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Manager struct {
|
||||||
|
types.ManagedObjectReference
|
||||||
|
|
||||||
|
c *vim25.Client
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewManager(c *vim25.Client) *Manager {
|
||||||
|
return &Manager{*c.ServiceContent.OvfManager, c}
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateDescriptor wraps methods.CreateDescriptor
|
||||||
|
func (m *Manager) CreateDescriptor(ctx context.Context, obj mo.Reference, cdp types.OvfCreateDescriptorParams) (*types.OvfCreateDescriptorResult, error) {
|
||||||
|
req := types.CreateDescriptor{
|
||||||
|
This: m.Reference(),
|
||||||
|
Obj: obj.Reference(),
|
||||||
|
Cdp: cdp,
|
||||||
|
}
|
||||||
|
|
||||||
|
res, err := methods.CreateDescriptor(ctx, m.c, &req)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return &res.Returnval, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateImportSpec wraps methods.CreateImportSpec
|
||||||
|
func (m *Manager) CreateImportSpec(ctx context.Context, ovfDescriptor string, resourcePool mo.Reference, datastore mo.Reference, cisp types.OvfCreateImportSpecParams) (*types.OvfCreateImportSpecResult, error) {
|
||||||
|
req := types.CreateImportSpec{
|
||||||
|
This: m.Reference(),
|
||||||
|
OvfDescriptor: ovfDescriptor,
|
||||||
|
ResourcePool: resourcePool.Reference(),
|
||||||
|
Datastore: datastore.Reference(),
|
||||||
|
Cisp: cisp,
|
||||||
|
}
|
||||||
|
|
||||||
|
res, err := methods.CreateImportSpec(ctx, m.c, &req)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return &res.Returnval, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// ParseDescriptor wraps methods.ParseDescriptor
|
||||||
|
func (m *Manager) ParseDescriptor(ctx context.Context, ovfDescriptor string, pdp types.OvfParseDescriptorParams) (*types.OvfParseDescriptorResult, error) {
|
||||||
|
req := types.ParseDescriptor{
|
||||||
|
This: m.Reference(),
|
||||||
|
OvfDescriptor: ovfDescriptor,
|
||||||
|
Pdp: pdp,
|
||||||
|
}
|
||||||
|
|
||||||
|
res, err := methods.ParseDescriptor(ctx, m.c, &req)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return &res.Returnval, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// ValidateHost wraps methods.ValidateHost
|
||||||
|
func (m *Manager) ValidateHost(ctx context.Context, ovfDescriptor string, host mo.Reference, vhp types.OvfValidateHostParams) (*types.OvfValidateHostResult, error) {
|
||||||
|
req := types.ValidateHost{
|
||||||
|
This: m.Reference(),
|
||||||
|
OvfDescriptor: ovfDescriptor,
|
||||||
|
Host: host.Reference(),
|
||||||
|
Vhp: vhp,
|
||||||
|
}
|
||||||
|
|
||||||
|
res, err := methods.ValidateHost(ctx, m.c, &req)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return &res.Returnval, nil
|
||||||
|
}
|
|
@ -0,0 +1,35 @@
|
||||||
|
/*
|
||||||
|
Copyright (c) 2015 VMware, Inc. All Rights Reserved.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package ovf
|
||||||
|
|
||||||
|
import (
|
||||||
|
"io"
|
||||||
|
|
||||||
|
"github.com/vmware/govmomi/vim25/xml"
|
||||||
|
)
|
||||||
|
|
||||||
|
func Unmarshal(r io.Reader) (*Envelope, error) {
|
||||||
|
var e Envelope
|
||||||
|
|
||||||
|
dec := xml.NewDecoder(r)
|
||||||
|
err := dec.Decode(&e)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return &e, nil
|
||||||
|
}
|
|
@ -572,6 +572,7 @@ github.com/vmware/govmomi/find
|
||||||
github.com/vmware/govmomi/list
|
github.com/vmware/govmomi/list
|
||||||
github.com/vmware/govmomi/nfc
|
github.com/vmware/govmomi/nfc
|
||||||
github.com/vmware/govmomi/object
|
github.com/vmware/govmomi/object
|
||||||
|
github.com/vmware/govmomi/ovf
|
||||||
github.com/vmware/govmomi/property
|
github.com/vmware/govmomi/property
|
||||||
github.com/vmware/govmomi/session
|
github.com/vmware/govmomi/session
|
||||||
github.com/vmware/govmomi/task
|
github.com/vmware/govmomi/task
|
||||||
|
|
|
@ -82,6 +82,17 @@ necessary for this build to succeed and can be found further down the page.
|
||||||
|
|
||||||
<%= partial "partials/helper/communicator/WinRM-not-required" %>
|
<%= partial "partials/helper/communicator/WinRM-not-required" %>
|
||||||
|
|
||||||
|
### Export Configuration
|
||||||
|
<%= partial "partials/builder/vsphere/common/ExportConfig" %>
|
||||||
|
|
||||||
|
### Optional:
|
||||||
|
|
||||||
|
<%= partial "partials/builder/vsphere/common/ExportConfig-not-required" %>
|
||||||
|
|
||||||
|
#### Output Configuration:
|
||||||
|
|
||||||
|
<%= partial "partials/builder/vsphere/common/OutputConfig-not-required" %>
|
||||||
|
|
||||||
## Working with Clusters
|
## Working with Clusters
|
||||||
#### Standalone Hosts
|
#### Standalone Hosts
|
||||||
Only use the `host` option. Optionally specify a `resource_pool`:
|
Only use the `host` option. Optionally specify a `resource_pool`:
|
||||||
|
|
|
@ -106,6 +106,17 @@ from the datastore. Example:
|
||||||
### Floppy Configuration
|
### Floppy Configuration
|
||||||
<%= partial "partials/builder/vsphere/iso/FloppyConfig-not-required" %>
|
<%= partial "partials/builder/vsphere/iso/FloppyConfig-not-required" %>
|
||||||
|
|
||||||
|
### Export Configuration
|
||||||
|
<%= partial "partials/builder/vsphere/common/ExportConfig" %>
|
||||||
|
|
||||||
|
### Optional:
|
||||||
|
|
||||||
|
<%= partial "partials/builder/vsphere/common/ExportConfig-not-required" %>
|
||||||
|
|
||||||
|
#### Output Configuration:
|
||||||
|
|
||||||
|
<%= partial "partials/builder/vsphere/common/OutputConfig-not-required" %>
|
||||||
|
|
||||||
### Extra Configuration Parameters
|
### Extra Configuration Parameters
|
||||||
<%= partial "partials/builder/vsphere/common/ConfigParamsConfig-not-required" %>
|
<%= partial "partials/builder/vsphere/common/ConfigParamsConfig-not-required" %>
|
||||||
|
|
||||||
|
|
|
@ -4,4 +4,5 @@
|
||||||
for linked clones. Defaults to `false`.
|
for linked clones. Defaults to `false`.
|
||||||
|
|
||||||
- `convert_to_template` (bool) - Convert VM to a template. Defaults to `false`.
|
- `convert_to_template` (bool) - Convert VM to a template. Defaults to `false`.
|
||||||
|
|
||||||
|
- `export` (\*common.ExportConfig) - Export
|
|
@ -0,0 +1,17 @@
|
||||||
|
<!-- Code generated from the comments of the ExportConfig struct in builder/vsphere/common/step_export.go; DO NOT EDIT MANUALLY -->
|
||||||
|
|
||||||
|
- `name` (string) - name of the ovf. defaults to the name of the VM
|
||||||
|
|
||||||
|
- `force` (bool) - overwrite ovf if it exists
|
||||||
|
|
||||||
|
- `images` (bool) - include iso and img image files that are attached to the VM
|
||||||
|
|
||||||
|
- `manifest` (string) - generate manifest using sha1, sha256, sha512. Defaults to 'sha256'. Use 'none' for no manifest.
|
||||||
|
|
||||||
|
- `options` ([]string) - ```json
|
||||||
|
...
|
||||||
|
"export": {
|
||||||
|
"options": ["mac"]
|
||||||
|
},
|
||||||
|
```
|
||||||
|
|
|
@ -0,0 +1,21 @@
|
||||||
|
<!-- Code generated from the comments of the ExportConfig struct in builder/vsphere/common/step_export.go; DO NOT EDIT MANUALLY -->
|
||||||
|
You may optionally export an ovf from VSphere to the instance running Packer.
|
||||||
|
|
||||||
|
Example usage:
|
||||||
|
|
||||||
|
```json
|
||||||
|
...
|
||||||
|
"vm_name": "example-ubuntu",
|
||||||
|
...
|
||||||
|
"export": {
|
||||||
|
"force": true,
|
||||||
|
"output_directory": "./output_vsphere"
|
||||||
|
},
|
||||||
|
```
|
||||||
|
The above configuration would create the following files:
|
||||||
|
|
||||||
|
```
|
||||||
|
./output_vsphere/example-ubuntu-disk-0.vmdk
|
||||||
|
./output_vsphere/example-ubuntu.mf
|
||||||
|
./output_vsphere/example-ubuntu.ovf
|
||||||
|
```
|
|
@ -0,0 +1,10 @@
|
||||||
|
<!-- Code generated from the comments of the OutputConfig struct in builder/vsphere/common/output_config.go; DO NOT EDIT MANUALLY -->
|
||||||
|
|
||||||
|
- `output_directory` (string) - This setting specifies the directory that
|
||||||
|
artifacts from the build, such as the virtual machine files and disks,
|
||||||
|
will be output to. The path to the directory may be relative or
|
||||||
|
absolute. If relative, the path is relative to the working directory
|
||||||
|
packer is executed from. This directory must not exist or, if
|
||||||
|
created, must be empty prior to running the builder. By default this is
|
||||||
|
"output-BUILDNAME" where "BUILDNAME" is the name of the build.
|
||||||
|
|
|
@ -4,4 +4,7 @@
|
||||||
for linked clones. Defaults to `false`.
|
for linked clones. Defaults to `false`.
|
||||||
|
|
||||||
- `convert_to_template` (bool) - Convert VM to a template. Defaults to `false`.
|
- `convert_to_template` (bool) - Convert VM to a template. Defaults to `false`.
|
||||||
|
|
||||||
|
- `export` (\*common.ExportConfig) - Configuration for exporting VM to an ovf file.
|
||||||
|
The VM will not be exported if no [Export Configuration](#export-configuration) is specified.
|
||||||
|
|
Loading…
Reference in New Issue